diff --git a/.github/actions/load/action.yml b/.github/actions/load/action.yml index 0102608dbd1..e3fc00dc6ae 100644 --- a/.github/actions/load/action.yml +++ b/.github/actions/load/action.yml @@ -24,10 +24,14 @@ runs: rm -r "$(pwd)"/* - name: Download artifact - uses: actions/download-artifact@v5 + uses: Wandalen/wretry.action@v3.8.0 with: - path: '${{ runner.temp }}' - name: '${{ inputs.name }}' + action: actions/download-artifact@v7 + attempt_limit: 2 + attempt_delay: 10000 + with: | + path: '${{ runner.temp }}' + name: '${{ inputs.name }}' - name: 'Untar working directory' shell: bash diff --git a/.github/actions/unzip-artifact/action.yml b/.github/actions/unzip-artifact/action.yml index 672fae7af85..a05c15a00cd 100644 --- a/.github/actions/unzip-artifact/action.yml +++ b/.github/actions/unzip-artifact/action.yml @@ -11,6 +11,9 @@ outputs: runs: using: 'composite' steps: + - name: 'Delay waiting for artifacts to be ready' + shell: bash + run: sleep 10 - name: 'Download artifact' id: download uses: actions/github-script@v8 diff --git a/.github/codeql/queries/autogen_fpDOMMethod.qll b/.github/codeql/queries/autogen_fpDOMMethod.qll index 61555d5852f..164a699e97b 100644 --- a/.github/codeql/queries/autogen_fpDOMMethod.qll +++ b/.github/codeql/queries/autogen_fpDOMMethod.qll @@ -7,9 +7,9 @@ class DOMMethod extends string { DOMMethod() { - ( this = "toDataURL" and weight = 32.78 and type = "HTMLCanvasElement" ) + ( this = "toDataURL" and weight = 32.64 and type = "HTMLCanvasElement" ) or - ( this = "getChannelData" and weight = 1033.52 and type = "AudioBuffer" ) + ( this = "getChannelData" and weight = 1009.41 and type = "AudioBuffer" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpEventProperty.qll b/.github/codeql/queries/autogen_fpEventProperty.qll index a102dc216aa..25ecd018f0f 100644 --- a/.github/codeql/queries/autogen_fpEventProperty.qll +++ b/.github/codeql/queries/autogen_fpEventProperty.qll @@ -7,21 +7,21 @@ class EventProperty extends string { EventProperty() { - ( this = "accelerationIncludingGravity" and weight = 195.95 and event = "devicemotion" ) + ( this = "candidate" and weight = 54.73 and event = "icecandidate" ) or - ( this = "beta" and weight = 889.02 and event = "deviceorientation" ) + ( this = "rotationRate" and weight = 63.55 and event = "devicemotion" ) or - ( this = "gamma" and weight = 318.9 and event = "deviceorientation" ) + ( this = "accelerationIncludingGravity" and weight = 205.08 and event = "devicemotion" ) or - ( this = "alpha" and weight = 748.66 and event = "deviceorientation" ) + ( this = "acceleration" and weight = 64.53 and event = "devicemotion" ) or - ( this = "candidate" and weight = 48.4 and event = "icecandidate" ) + ( this = "alpha" and weight = 784.67 and event = "deviceorientation" ) or - ( this = "acceleration" and weight = 59.13 and event = "devicemotion" ) + ( this = "beta" and weight = 801.42 and event = "deviceorientation" ) or - ( this = "rotationRate" and weight = 58.73 and event = "devicemotion" ) + ( this = "gamma" and weight = 300.01 and event = "deviceorientation" ) or - ( this = "absolute" and weight = 480.46 and event = "deviceorientation" ) + ( this = "absolute" and weight = 281.45 and event = "deviceorientation" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalConstructor.qll b/.github/codeql/queries/autogen_fpGlobalConstructor.qll index 1bd3776448a..8feceaae940 100644 --- a/.github/codeql/queries/autogen_fpGlobalConstructor.qll +++ b/.github/codeql/queries/autogen_fpGlobalConstructor.qll @@ -6,15 +6,15 @@ class GlobalConstructor extends string { GlobalConstructor() { - ( this = "OfflineAudioContext" and weight = 1249.69 ) + ( this = "SharedWorker" and weight = 74.12 ) or - ( this = "SharedWorker" and weight = 78.96 ) + ( this = "OfflineAudioContext" and weight = 1062.83 ) or - ( this = "RTCPeerConnection" and weight = 36.22 ) + ( this = "RTCPeerConnection" and weight = 36.17 ) or - ( this = "Gyroscope" and weight = 94.31 ) + ( this = "Gyroscope" and weight = 100.27 ) or - ( this = "AudioWorkletNode" and weight = 106.77 ) + ( this = "AudioWorkletNode" and weight = 145.12 ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalObjectProperty0.qll b/.github/codeql/queries/autogen_fpGlobalObjectProperty0.qll index 622b4097377..19489a50149 100644 --- a/.github/codeql/queries/autogen_fpGlobalObjectProperty0.qll +++ b/.github/codeql/queries/autogen_fpGlobalObjectProperty0.qll @@ -7,59 +7,57 @@ class GlobalObjectProperty0 extends string { GlobalObjectProperty0() { - ( this = "availWidth" and weight = 62.91 and global0 = "screen" ) + ( this = "availHeight" and weight = 65.33 and global0 = "screen" ) or - ( this = "availHeight" and weight = 66.51 and global0 = "screen" ) + ( this = "availWidth" and weight = 61.95 and global0 = "screen" ) or - ( this = "colorDepth" and weight = 36.87 and global0 = "screen" ) + ( this = "colorDepth" and weight = 38.5 and global0 = "screen" ) or - ( this = "pixelDepth" and weight = 43.1 and global0 = "screen" ) + ( this = "availTop" and weight = 1305.37 and global0 = "screen" ) or - ( this = "availLeft" and weight = 730.43 and global0 = "screen" ) + ( this = "plugins" and weight = 15.16 and global0 = "navigator" ) or - ( this = "availTop" and weight = 1485.89 and global0 = "screen" ) + ( this = "deviceMemory" and weight = 64.15 and global0 = "navigator" ) or - ( this = "orientation" and weight = 33.81 and global0 = "screen" ) + ( this = "getBattery" and weight = 41.16 and global0 = "navigator" ) or - ( this = "vendorSub" and weight = 1822.98 and global0 = "navigator" ) + ( this = "webdriver" and weight = 27.64 and global0 = "navigator" ) or - ( this = "productSub" and weight = 381.55 and global0 = "navigator" ) + ( this = "permission" and weight = 24.67 and global0 = "Notification" ) or - ( this = "plugins" and weight = 15.37 and global0 = "navigator" ) + ( this = "storage" and weight = 35.77 and global0 = "navigator" ) or - ( this = "mimeTypes" and weight = 15.39 and global0 = "navigator" ) + ( this = "onLine" and weight = 18.84 and global0 = "navigator" ) or - ( this = "webkitTemporaryStorage" and weight = 32.87 and global0 = "navigator" ) + ( this = "pixelDepth" and weight = 45.77 and global0 = "screen" ) or - ( this = "hardwareConcurrency" and weight = 55.54 and global0 = "navigator" ) + ( this = "availLeft" and weight = 624.44 and global0 = "screen" ) or - ( this = "appCodeName" and weight = 167.7 and global0 = "navigator" ) + ( this = "orientation" and weight = 34.16 and global0 = "screen" ) or - ( this = "onLine" and weight = 18.14 and global0 = "navigator" ) + ( this = "vendorSub" and weight = 1873.27 and global0 = "navigator" ) or - ( this = "webdriver" and weight = 28.99 and global0 = "navigator" ) + ( this = "productSub" and weight = 381.87 and global0 = "navigator" ) or - ( this = "keyboard" and weight = 5673.26 and global0 = "navigator" ) + ( this = "webkitTemporaryStorage" and weight = 37.97 and global0 = "navigator" ) or - ( this = "mediaDevices" and weight = 123.32 and global0 = "navigator" ) + ( this = "hardwareConcurrency" and weight = 51.78 and global0 = "navigator" ) or - ( this = "storage" and weight = 30.23 and global0 = "navigator" ) + ( this = "appCodeName" and weight = 173.35 and global0 = "navigator" ) or - ( this = "deviceMemory" and weight = 62.29 and global0 = "navigator" ) + ( this = "keyboard" and weight = 1722.82 and global0 = "navigator" ) or - ( this = "mediaCapabilities" and weight = 148.31 and global0 = "navigator" ) + ( this = "mediaDevices" and weight = 149.07 and global0 = "navigator" ) or - ( this = "permissions" and weight = 92.01 and global0 = "navigator" ) + ( this = "mediaCapabilities" and weight = 142.34 and global0 = "navigator" ) or - ( this = "permission" and weight = 25.87 and global0 = "Notification" ) + ( this = "permissions" and weight = 89.71 and global0 = "navigator" ) or - ( this = "getBattery" and weight = 40.45 and global0 = "navigator" ) + ( this = "webkitPersistentStorage" and weight = 134.12 and global0 = "navigator" ) or - ( this = "webkitPersistentStorage" and weight = 121.43 and global0 = "navigator" ) + ( this = "requestMediaKeySystemAccess" and weight = 18.22 and global0 = "navigator" ) or - ( this = "requestMediaKeySystemAccess" and weight = 22.53 and global0 = "navigator" ) - or - ( this = "getGamepads" and weight = 275.28 and global0 = "navigator" ) + ( this = "getGamepads" and weight = 209.55 and global0 = "navigator" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalObjectProperty1.qll b/.github/codeql/queries/autogen_fpGlobalObjectProperty1.qll index 3be175f2c11..4ba664c998f 100644 --- a/.github/codeql/queries/autogen_fpGlobalObjectProperty1.qll +++ b/.github/codeql/queries/autogen_fpGlobalObjectProperty1.qll @@ -8,7 +8,7 @@ class GlobalObjectProperty1 extends string { GlobalObjectProperty1() { - ( this = "enumerateDevices" and weight = 361.7 and global0 = "navigator" and global1 = "mediaDevices" ) + ( this = "enumerateDevices" and weight = 595.56 and global0 = "navigator" and global1 = "mediaDevices" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalTypeProperty0.qll b/.github/codeql/queries/autogen_fpGlobalTypeProperty0.qll index 489d3f0f3ae..b26e3689251 100644 --- a/.github/codeql/queries/autogen_fpGlobalTypeProperty0.qll +++ b/.github/codeql/queries/autogen_fpGlobalTypeProperty0.qll @@ -7,11 +7,11 @@ class GlobalTypeProperty0 extends string { GlobalTypeProperty0() { - ( this = "x" and weight = 5673.26 and global0 = "Gyroscope" ) + ( this = "x" and weight = 4255.55 and global0 = "Gyroscope" ) or - ( this = "y" and weight = 5673.26 and global0 = "Gyroscope" ) + ( this = "y" and weight = 4255.55 and global0 = "Gyroscope" ) or - ( this = "z" and weight = 5673.26 and global0 = "Gyroscope" ) + ( this = "z" and weight = 4255.55 and global0 = "Gyroscope" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalTypeProperty1.qll b/.github/codeql/queries/autogen_fpGlobalTypeProperty1.qll index 2f290d30132..084e91305b6 100644 --- a/.github/codeql/queries/autogen_fpGlobalTypeProperty1.qll +++ b/.github/codeql/queries/autogen_fpGlobalTypeProperty1.qll @@ -8,7 +8,7 @@ class GlobalTypeProperty1 extends string { GlobalTypeProperty1() { - ( this = "resolvedOptions" and weight = 18.94 and global0 = "Intl" and global1 = "DateTimeFormat" ) + ( this = "resolvedOptions" and weight = 19.01 and global0 = "Intl" and global1 = "DateTimeFormat" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpGlobalVar.qll b/.github/codeql/queries/autogen_fpGlobalVar.qll index debc39522ee..a28f1c7772c 100644 --- a/.github/codeql/queries/autogen_fpGlobalVar.qll +++ b/.github/codeql/queries/autogen_fpGlobalVar.qll @@ -6,23 +6,23 @@ class GlobalVar extends string { GlobalVar() { - ( this = "devicePixelRatio" and weight = 18.84 ) + ( this = "devicePixelRatio" and weight = 18.39 ) or - ( this = "outerWidth" and weight = 104.3 ) + ( this = "screenX" and weight = 366.36 ) or - ( this = "outerHeight" and weight = 177.3 ) + ( this = "screenY" and weight = 320.66 ) or - ( this = "indexedDB" and weight = 21.68 ) + ( this = "outerWidth" and weight = 104.67 ) or - ( this = "screenX" and weight = 411.93 ) + ( this = "outerHeight" and weight = 154.1 ) or - ( this = "screenY" and weight = 369.99 ) + ( this = "screenLeft" and weight = 321.49 ) or - ( this = "screenLeft" and weight = 344.06 ) + ( this = "screenTop" and weight = 322.32 ) or - ( this = "screenTop" and weight = 343.13 ) + ( this = "indexedDB" and weight = 23.36 ) or - ( this = "openDatabase" and weight = 128.91 ) + ( this = "openDatabase" and weight = 146.11 ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpRenderingContextProperty.qll b/.github/codeql/queries/autogen_fpRenderingContextProperty.qll index 1f23b1a5057..e508d42520b 100644 --- a/.github/codeql/queries/autogen_fpRenderingContextProperty.qll +++ b/.github/codeql/queries/autogen_fpRenderingContextProperty.qll @@ -7,35 +7,35 @@ class RenderingContextProperty extends string { RenderingContextProperty() { - ( this = "getImageData" and weight = 55.51 and contextType = "2d" ) + ( this = "getExtension" and weight = 24.59 and contextType = "webgl" ) or - ( this = "getParameter" and weight = 30.58 and contextType = "webgl" ) + ( this = "getParameter" and weight = 28.11 and contextType = "webgl" ) or - ( this = "measureText" and weight = 46.82 and contextType = "2d" ) + ( this = "getImageData" and weight = 62.25 and contextType = "2d" ) or - ( this = "getParameter" and weight = 70.22 and contextType = "webgl2" ) + ( this = "measureText" and weight = 43.06 and contextType = "2d" ) or - ( this = "getShaderPrecisionFormat" and weight = 128.74 and contextType = "webgl2" ) + ( this = "getParameter" and weight = 67.61 and contextType = "webgl2" ) or - ( this = "getExtension" and weight = 71.78 and contextType = "webgl2" ) + ( this = "getShaderPrecisionFormat" and weight = 138.74 and contextType = "webgl2" ) or - ( this = "getContextAttributes" and weight = 190.28 and contextType = "webgl2" ) + ( this = "getExtension" and weight = 69.66 and contextType = "webgl2" ) or - ( this = "getSupportedExtensions" and weight = 560.85 and contextType = "webgl2" ) + ( this = "getContextAttributes" and weight = 201.04 and contextType = "webgl2" ) or - ( this = "getExtension" and weight = 26.27 and contextType = "webgl" ) + ( this = "getSupportedExtensions" and weight = 360.36 and contextType = "webgl2" ) or - ( this = "getShaderPrecisionFormat" and weight = 1175.17 and contextType = "webgl" ) + ( this = "readPixels" and weight = 24.33 and contextType = "webgl" ) or - ( this = "getContextAttributes" and weight = 1998.53 and contextType = "webgl" ) + ( this = "getShaderPrecisionFormat" and weight = 1347.35 and contextType = "webgl" ) or - ( this = "getSupportedExtensions" and weight = 1388.64 and contextType = "webgl" ) + ( this = "getContextAttributes" and weight = 2411.38 and contextType = "webgl" ) or - ( this = "readPixels" and weight = 22.43 and contextType = "webgl" ) + ( this = "getSupportedExtensions" and weight = 1484.82 and contextType = "webgl" ) or - ( this = "isPointInPath" and weight = 5210.68 and contextType = "2d" ) + ( this = "isPointInPath" and weight = 4255.55 and contextType = "2d" ) or - ( this = "readPixels" and weight = 610.19 and contextType = "webgl2" ) + ( this = "readPixels" and weight = 1004.16 and contextType = "webgl2" ) } float getWeight() { diff --git a/.github/codeql/queries/autogen_fpSensorProperty.qll b/.github/codeql/queries/autogen_fpSensorProperty.qll index 74bf3e4f988..bfc5c329068 100644 --- a/.github/codeql/queries/autogen_fpSensorProperty.qll +++ b/.github/codeql/queries/autogen_fpSensorProperty.qll @@ -6,7 +6,7 @@ class SensorProperty extends string { SensorProperty() { - ( this = "start" and weight = 92.53 ) + ( this = "start" and weight = 105.54 ) } float getWeight() { diff --git a/.github/workflows/PR-assignment-deps.yml b/.github/workflows/PR-assignment-deps.yml index 587555b705c..2d7fce88837 100644 --- a/.github/workflows/PR-assignment-deps.yml +++ b/.github/workflows/PR-assignment-deps.yml @@ -20,7 +20,7 @@ jobs: run: | npx gulp build - name: Upload dependencies.json - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: dependencies.json path: ./build/dist/dependencies.json @@ -28,7 +28,7 @@ jobs: run: | echo '{ "prNo": ${{ github.event.pull_request.number }} }' >> ${{ runner.temp}}/prInfo.json - name: Upload PR info - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: prInfo path: ${{ runner.temp}}/prInfo.json diff --git a/.github/workflows/jscpd.yml b/.github/workflows/jscpd.yml index c3021b2ced7..a4b2a14861f 100644 --- a/.github/workflows/jscpd.yml +++ b/.github/workflows/jscpd.yml @@ -56,7 +56,7 @@ jobs: - name: Upload unfiltered jscpd report if: always() - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: unfiltered-jscpd-report path: ./jscpd-report.json @@ -89,7 +89,7 @@ jobs: - name: Upload filtered jscpd report if: env.filtered_report_exists == 'true' - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: filtered-jscpd-report path: ./filtered-jscpd-report.json @@ -119,7 +119,7 @@ jobs: - name: Upload comment data if: env.filtered_report_exists == 'true' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: comment path: ${{ runner.temp }}/comment.json diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index 39fdcc4067b..e4a736c0b25 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -117,7 +117,7 @@ jobs: - name: Upload comment data if: ${{ steps.comment.outputs.result == 'true' }} - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: comment path: ${{ runner.temp }}/comment.json diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 1cc6808f29f..924683ec0e0 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -71,6 +71,11 @@ on: BROWSERSTACK_ACCESS_KEY: description: "Browserstack access key" + +permissions: + contents: read + actions: read + jobs: checkout: name: "Define chunks" @@ -201,7 +206,7 @@ jobs: - name: 'Save coverage result' if: ${{ steps.coverage.outputs.coverage }} - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: coverage-partial-${{inputs.test-cmd}}-${{ matrix.chunk-no }} path: ./build/coverage @@ -224,7 +229,7 @@ jobs: name: ${{ needs.build.outputs.built-key }} - name: Download coverage results - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: path: ./build/coverage pattern: coverage-partial-${{ inputs.test-cmd }}-* diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1209ca2057d..ed12de000c8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,10 @@ on: pull_request: types: [opened, synchronize, reopened] +permissions: + contents: read + actions: read + concurrency: group: test-${{ github.head_ref || github.ref }} cancel-in-progress: true diff --git a/AGENTS.md b/AGENTS.md index ce4e1353a9a..c340fee56ff 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -45,3 +45,6 @@ This file contains instructions for the Codex agent and its friends when working - Avoid running Babel over the entire project for incremental test runs. - Use `gulp serve-and-test --file ` or `gulp test --file` so Babel processes only the specified files. - Do not invoke commands that rebuild all modules when only a subset are changed. + +## Additional context +- for additional context on repo history, consult https://github.com/prebid/github-activity-db/blob/main/CLAUDE.md on how to download and access repo history in a database you can search locally. diff --git a/creative/constants.js b/creative/constants.js index 26922cd8d79..2cf79d6202b 100644 --- a/creative/constants.js +++ b/creative/constants.js @@ -1,8 +1,8 @@ // eslint-disable-next-line prebid/validate-imports -import {AD_RENDER_FAILED_REASON, EVENTS, MESSAGES} from '../src/constants.js'; +import { AD_RENDER_FAILED_REASON, EVENTS, MESSAGES } from '../src/constants.js'; // eslint-disable-next-line prebid/validate-imports -export {PB_LOCATOR} from '../src/constants.js'; +export { PB_LOCATOR } from '../src/constants.js'; export const MESSAGE_REQUEST = MESSAGES.REQUEST; export const MESSAGE_RESPONSE = MESSAGES.RESPONSE; export const MESSAGE_EVENT = MESSAGES.EVENT; diff --git a/creative/crossDomain.js b/creative/crossDomain.js index 550f944ba5f..baa1cfa7a57 100644 --- a/creative/crossDomain.js +++ b/creative/crossDomain.js @@ -40,13 +40,13 @@ export function renderer(win) { } catch (e) { } - return function ({adId, pubUrl, clickUrl}) { + return function ({ adId, pubUrl, clickUrl }) { const pubDomain = new URL(pubUrl, window.location).origin; function sendMessage(type, payload, responseListener) { const channel = new MessageChannel(); channel.port1.onmessage = guard(responseListener); - target.postMessage(JSON.stringify(Object.assign({message: type, adId}, payload)), pubDomain, [channel.port2]); + target.postMessage(JSON.stringify(Object.assign({ message: type, adId }, payload)), pubDomain, [channel.port2]); } function onError(e) { @@ -88,8 +88,8 @@ export function renderer(win) { const W = renderer.contentWindow; // NOTE: on Firefox, `Promise.resolve(P)` or `new Promise((resolve) => resolve(P))` // does not appear to work if P comes from another frame - W.Promise.resolve(W.render(data, {sendMessage, mkFrame}, win)).then( - () => sendMessage(MESSAGE_EVENT, {event: EVENT_AD_RENDER_SUCCEEDED}), + W.Promise.resolve(W.render(data, { sendMessage, mkFrame }, win)).then( + () => sendMessage(MESSAGE_EVENT, { event: EVENT_AD_RENDER_SUCCEEDED }), onError ); }); @@ -101,7 +101,7 @@ export function renderer(win) { } sendMessage(MESSAGE_REQUEST, { - options: {clickUrl} + options: { clickUrl } }, onMessage); }; } diff --git a/creative/renderers/display/renderer.js b/creative/renderers/display/renderer.js index e2f6451bf62..7cbe78a93ef 100644 --- a/creative/renderers/display/renderer.js +++ b/creative/renderers/display/renderer.js @@ -1,8 +1,8 @@ import { registerReportingObserver } from '../../reporting.js'; import { BROWSER_INTERVENTION, MESSAGE_EVENT } from '../../constants.js'; -import {ERROR_NO_AD} from './constants.js'; +import { ERROR_NO_AD } from './constants.js'; -export function render({ad, adUrl, width, height, instl}, {mkFrame, sendMessage}, win) { +export function render({ ad, adUrl, width, height, instl }, { mkFrame, sendMessage }, win) { registerReportingObserver((report) => { sendMessage(MESSAGE_EVENT, { event: BROWSER_INTERVENTION, @@ -24,7 +24,7 @@ export function render({ad, adUrl, width, height, instl}, {mkFrame, sendMessage} }); } const doc = win.document; - const attrs = {width: width ?? '100%', height: height ?? '100%'}; + const attrs = { width: width ?? '100%', height: height ?? '100%' }; if (adUrl && !ad) { attrs.src = adUrl; } else { diff --git a/creative/renderers/native/renderer.js b/creative/renderers/native/renderer.js index 86236c8f948..badbc121fb5 100644 --- a/creative/renderers/native/renderer.js +++ b/creative/renderers/native/renderer.js @@ -1,9 +1,9 @@ import { registerReportingObserver } from '../../reporting.js'; import { BROWSER_INTERVENTION, MESSAGE_EVENT } from '../../constants.js'; -import {ACTION_CLICK, ACTION_IMP, ACTION_RESIZE, MESSAGE_NATIVE, ORTB_ASSETS} from './constants.js'; +import { ACTION_CLICK, ACTION_IMP, ACTION_RESIZE, MESSAGE_NATIVE, ORTB_ASSETS } from './constants.js'; -export function getReplacer(adId, {assets = [], ortb, nativeKeys = {}}) { - const assetValues = Object.fromEntries((assets).map(({key, value}) => [key, value])); +export function getReplacer(adId, { assets = [], ortb, nativeKeys = {} }) { + const assetValues = Object.fromEntries((assets).map(({ key, value }) => [key, value])); let repl = Object.fromEntries( Object.entries(nativeKeys).flatMap(([name, key]) => { const value = assetValues.hasOwnProperty(name) ? assetValues[name] : undefined; @@ -58,7 +58,7 @@ function getInnerHTML(node) { } export function getAdMarkup(adId, nativeData, replacer, win, load = loadScript) { - const {rendererUrl, assets, ortb, adTemplate} = nativeData; + const { rendererUrl, assets, ortb, adTemplate } = nativeData; const doc = win.document; if (rendererUrl) { return load(rendererUrl, doc).then(() => { @@ -74,14 +74,14 @@ export function getAdMarkup(adId, nativeData, replacer, win, load = loadScript) } } -export function render({adId, native}, {sendMessage}, win, getMarkup = getAdMarkup) { +export function render({ adId, native }, { sendMessage }, win, getMarkup = getAdMarkup) { registerReportingObserver((report) => { sendMessage(MESSAGE_EVENT, { event: BROWSER_INTERVENTION, intervention: report }); }, ['intervention']); - const {head, body} = win.document; + const { head, body } = win.document; const resize = () => { // force redraw - for some reason this is needed to get the right dimensions body.style.display = 'none'; @@ -103,13 +103,13 @@ export function render({adId, native}, {sendMessage}, win, getMarkup = getAdMark return getMarkup(adId, native, replacer, win).then(markup => { replaceMarkup(body, markup); if (typeof win.postRenderAd === 'function') { - win.postRenderAd({adId, ...native}); + win.postRenderAd({ adId, ...native }); } win.document.querySelectorAll('.pb-click').forEach(el => { const assetId = el.getAttribute('hb_native_asset_id'); - el.addEventListener('click', () => sendMessage(MESSAGE_NATIVE, {action: ACTION_CLICK, assetId})); + el.addEventListener('click', () => sendMessage(MESSAGE_NATIVE, { action: ACTION_CLICK, assetId })); }); - sendMessage(MESSAGE_NATIVE, {action: ACTION_IMP}); + sendMessage(MESSAGE_NATIVE, { action: ACTION_IMP }); win.document.readyState === 'complete' ? resize() : win.onload = resize; }); } diff --git a/eslint.config.js b/eslint.config.js index a9b7fe04153..90b7313db50 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -9,6 +9,7 @@ const path = require('path'); const _ = require('lodash'); const tseslint = require('typescript-eslint'); const {getSourceFolders} = require('./gulpHelpers.js'); +const APPROVED_LOAD_EXTERNAL_SCRIPT_PATHS = require('./plugins/eslint/approvedLoadExternalScriptPaths.js'); function jsPattern(name) { return [`${name}/**/*.js`, `${name}/**/*.mjs`] @@ -106,10 +107,13 @@ module.exports = [ }, rules: { 'comma-dangle': 'off', + '@stylistic/comma-dangle': 'off', semi: 'off', + '@stylistic/semi': 'off', 'no-undef': 2, 'no-console': 'error', 'space-before-function-paren': 'off', + '@stylistic/space-before-function-paren': 'off', 'import/extensions': ['error', 'ignorePackages'], 'no-restricted-syntax': [ 'error', @@ -122,6 +126,13 @@ module.exports = [ message: "Assigning a function to 'logResult, 'logMessage', 'logInfo', 'logWarn', or 'logError' is not allowed." }, ], + 'no-restricted-imports': [ + 'error', { + patterns: [ + '**/src/adloader.js' + ] + } + ], // Exceptions below this line are temporary (TM), so that eslint can be added into the CI process. // Violations of these styles should be fixed, and the exceptions removed over time. @@ -156,19 +167,9 @@ module.exports = [ 'object-shorthand': 'off', 'prefer-regex-literals': 'off', 'no-case-declarations': 'off', - 'no-useless-catch': 'off', '@stylistic/quotes': 'off', '@stylistic/quote-props': 'off', - '@stylistic/array-bracket-spacing': 'off', - '@stylistic/object-curly-spacing': 'off', - '@stylistic/semi': 'off', - '@stylistic/space-before-function-paren': 'off', '@stylistic/multiline-ternary': 'off', - '@stylistic/computed-property-spacing': 'off', - '@stylistic/lines-between-class-members': 'off', - '@stylistic/comma-dangle': 'off', - '@stylistic/object-curly-newline': 'off', - '@stylistic/object-property-newline': 'off', } }, ...Object.entries(allowedImports).map(([path, allowed]) => { @@ -273,4 +274,22 @@ module.exports = [ '@typescript-eslint/no-require-imports': 'off' } }, -] + // Override: allow loadExternalScript import in approved files (excluding BidAdapters) + { + files: APPROVED_LOAD_EXTERNAL_SCRIPT_PATHS.filter(p => !p.includes('BidAdapter')).map(p => { + // If path doesn't end with .js/.ts/.mjs, treat as folder pattern + if (!p.match(/\.(js|ts|mjs)$/)) { + return `${p}/**/*.{js,ts,mjs}`; + } + return p; + }), + rules: { + 'no-restricted-imports': [ + 'error', + { + patterns: [] + } + ], + } + }, + ] diff --git a/gulpfile.js b/gulpfile.js index e5a4db41884..cc543ad73ec 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -53,7 +53,7 @@ function bundleToStdout() { bundleToStdout.displayName = 'bundle-to-stdout'; function clean() { - return gulp.src(['build', 'dist'], { + return gulp.src(['.cache', 'build', 'dist'], { read: false, allowEmpty: true }) diff --git a/integrationExamples/gpt/adcluster_banner_example.html b/integrationExamples/gpt/adcluster_banner_example.html new file mode 100644 index 00000000000..4f7bf646bb9 --- /dev/null +++ b/integrationExamples/gpt/adcluster_banner_example.html @@ -0,0 +1,115 @@ + + + + + Adcluster Adapter Test + + + + + + + + + + +

Prebid.js Live Adapter Test

+
+ + + + diff --git a/integrationExamples/gpt/adcluster_video_example.html b/integrationExamples/gpt/adcluster_video_example.html new file mode 100644 index 00000000000..0a309b24749 --- /dev/null +++ b/integrationExamples/gpt/adcluster_video_example.html @@ -0,0 +1,291 @@ + + + + + Adcluster Adapter – Outstream Test with Fallback + + + + + + + + + +

Adcluster Adapter – Outstream Test (AN renderer + IMA fallback)

+
+ +
+ + + + diff --git a/integrationExamples/gpt/insurads.html b/integrationExamples/gpt/insurads.html new file mode 100644 index 00000000000..92f6b7df8b2 --- /dev/null +++ b/integrationExamples/gpt/insurads.html @@ -0,0 +1,121 @@ + + + + + + + + + + + + + +

Prebid.js Test

+
Div-1
+
+ +
+ + + + diff --git a/integrationExamples/gpt/mediago_test.html b/integrationExamples/gpt/mediago_test.html index d09e814eda4..5df9129ef3b 100644 --- a/integrationExamples/gpt/mediago_test.html +++ b/integrationExamples/gpt/mediago_test.html @@ -121,116 +121,6 @@ }] } ]; - - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - - // Store request information for debugging - var requestLogs = []; - - // Intercept AJAX requests to view sent data - var originalOpen = XMLHttpRequest.prototype.open; - var originalSend = XMLHttpRequest.prototype.send; - - XMLHttpRequest.prototype.open = function(method, url, ...args) { - this._url = url; - this._method = method; - return originalOpen.apply(this, [method, url, ...args]); - }; - - XMLHttpRequest.prototype.send = function(data) { - if (this._url && this._url.includes('mediago.io')) { - try { - var requestData = JSON.parse(data); - requestLogs.push({ - url: this._url, - method: this._method, - data: requestData, - timestamp: new Date().toISOString() - }); - console.log('Mediago Request:', requestData); - - // Check if IDs in imp array are unique - if (requestData.imp && Array.isArray(requestData.imp)) { - var ids = requestData.imp.map(imp => imp.id).filter(Boolean); - var uniqueIds = [...new Set(ids)]; - var isUnique = ids.length === uniqueIds.length; - - console.log('ID Uniqueness Check:'); - console.log(' Total IDs:', ids.length); - console.log(' Unique IDs:', uniqueIds.length); - console.log(' Is Unique:', isUnique ? '✓ Yes' : '✗ No'); - console.log(' ID List:', ids); - - if (!isUnique) { - console.warn('Warning: Duplicate IDs found!', ids); - } - - updateDebugInfo(requestData, isUnique, ids, uniqueIds); - } - } catch (e) { - console.error('Failed to parse request data:', e); - } - } - - // Listen for response - this.addEventListener('load', function() { - if (this._url && this._url.includes('mediago.io')) { - try { - var response = JSON.parse(this.responseText); - console.log('Mediago Response:', response); - updateResponseInfo(response); - } catch (e) { - console.error('Failed to parse response data:', e); - } - } - }); - - return originalSend.apply(this, [data]); - }; - - function updateDebugInfo(requestData, isUnique, ids, uniqueIds) { - var debugDiv = document.getElementById('debug-info'); - if (!debugDiv) return; - - var html = '

Request Debug Info

'; - html += '

Time: ' + new Date().toLocaleString() + '

'; - html += '

ID Uniqueness: ' + (isUnique ? '✓ Pass' : '✗ Fail') + '

'; - html += '

Total IDs: ' + ids.length + '

'; - html += '

Unique IDs: ' + uniqueIds.length + '

'; - html += '

ID List:

'; - html += ''; - - html += '

Request Data (imp section):

'; - html += '
' + JSON.stringify(requestData.imp, null, 2) + '
'; - - debugDiv.innerHTML = html; - } - - function updateResponseInfo(response) { - var responseDiv = document.getElementById('response-info'); - if (!responseDiv) return; - - var html = '

Response Info

'; - html += '

Time: ' + new Date().toLocaleString() + '

'; - if (response.seatbid && response.seatbid.length > 0) { - html += '

Number of bids returned: ' + response.seatbid[0].bid.length + '

'; - html += '
' + JSON.stringify(response, null, 2) + '
'; - } else { - html += '

No valid response received

'; - } - - responseDiv.innerHTML = html; - } - @@ -282,6 +172,9 @@

Ad Unit 3 (728x90)

pbjs.que.push(function() { console.log('Prebid.js loaded'); + // Enable TID (Transaction ID) transmission - required since Prebid 8 for ortb2Imp.ext.tid to reach bidders + pbjs.setConfig({ enableTIDs: true }); + // Set pageUrl and ortb2 site configuration to simulate other site // pageUrl will override Prebid's referrer detection // pbjs.setConfig({ @@ -420,7 +313,6 @@

Ad Unit 3 (728x90)

function clearDebug() { document.getElementById('debug-info').innerHTML = '

Debug info cleared

'; document.getElementById('response-info').innerHTML = '

Response info cleared

'; - requestLogs = []; // Clear ad containers ['mediago-ad-1', 'mediago-ad-2', 'mediago-ad-3'].forEach(function(id) { diff --git a/integrationExamples/gpt/neuwoRtdProvider_example.html b/integrationExamples/gpt/neuwoRtdProvider_example.html index 3d6fef98995..68c95fe8b4f 100644 --- a/integrationExamples/gpt/neuwoRtdProvider_example.html +++ b/integrationExamples/gpt/neuwoRtdProvider_example.html @@ -26,28 +26,28 @@ var adUnits = [ { - code: '/19968336/header-bid-tag-1', + code: "/19968336/header-bid-tag-1", mediaTypes: { banner: { sizes: div_1_sizes } }, bids: [{ - bidder: 'appnexus', + bidder: "appnexus", params: { placementId: 13144370 } }] }, { - code: '/19968336/header-bid-tag-1', + code: "/19968336/header-bid-tag-1", mediaTypes: { banner: { sizes: div_2_sizes } }, bids: [{ - bidder: 'appnexus', + bidder: "appnexus", params: { placementId: 13144370 } @@ -86,12 +86,12 @@ // Custom Timeout logic in onSettingsUpdate() googletag.cmd.push(function () { - googletag.defineSlot('/19968336/header-bid-tag-1', div_1_sizes, 'div-1').addService(googletag.pubads()); + googletag.defineSlot("/19968336/header-bid-tag-1", div_1_sizes, "div-1").addService(googletag.pubads()); googletag.pubads().enableSingleRequest(); googletag.enableServices(); }); googletag.cmd.push(function () { - googletag.defineSlot('/19968336/header-bid-tag-1', div_2_sizes, 'div-2').addService(googletag.pubads()); + googletag.defineSlot("/19968336/header-bid-tag-1", div_2_sizes, "div-2").addService(googletag.pubads()); googletag.pubads().enableSingleRequest(); googletag.enableServices(); }); @@ -99,47 +99,65 @@ // 3. User Triggered Setup (RTD Module) function onSettingsUpdate() { - const inputNeuwoApiToken = document.getElementById('neuwo-api-token'); - const neuwoApiToken = inputNeuwoApiToken ? inputNeuwoApiToken.value : ''; + const inputNeuwoApiToken = document.getElementById("neuwo-api-token"); + const neuwoApiToken = inputNeuwoApiToken ? inputNeuwoApiToken.value : ""; if (!neuwoApiToken) { - alert('Please enter your token for Neuwo AI API to the field'); + alert("Please enter your token for Neuwo AI API to the field"); if (inputNeuwoApiToken) inputNeuwoApiToken.focus(); return; } - const inputNeuwoApiUrl = document.getElementById('neuwo-api-url'); - const neuwoApiUrl = inputNeuwoApiUrl ? inputNeuwoApiUrl.value : ''; + const inputNeuwoApiUrl = document.getElementById("neuwo-api-url"); + const neuwoApiUrl = inputNeuwoApiUrl ? inputNeuwoApiUrl.value : ""; if (!neuwoApiUrl) { - alert('Please enter Neuwo AI API url to the field'); + alert("Please enter Neuwo AI API url to the field"); if (inputNeuwoApiUrl) inputNeuwoApiUrl.focus(); return; } - const inputWebsiteToAnalyseUrl = document.getElementById('website-to-analyse-url'); + const inputWebsiteToAnalyseUrl = document.getElementById("website-to-analyse-url"); const websiteToAnalyseUrl = inputWebsiteToAnalyseUrl ? inputWebsiteToAnalyseUrl.value : undefined; - const inputIabContentTaxonomyVersion = document.getElementById('iab-content-taxonomy-version'); + const inputIabContentTaxonomyVersion = document.getElementById("iab-content-taxonomy-version"); const iabContentTaxonomyVersion = inputIabContentTaxonomyVersion ? inputIabContentTaxonomyVersion.value : undefined; // Cache Option - const inputEnableCache = document.getElementById('enable-cache'); + const inputEnableCache = document.getElementById("enable-cache"); const enableCache = inputEnableCache ? inputEnableCache.checked : undefined; + // OpenRTB 2.5 Category Fields Option + const inputEnableOrtb25Fields = document.getElementById("enable-ortb25-fields"); + const enableOrtb25Fields = inputEnableOrtb25Fields ? inputEnableOrtb25Fields.checked : true; + // URL Stripping Options - const inputStripAllQueryParams = document.getElementById('strip-all-query-params'); + const inputStripAllQueryParams = document.getElementById("strip-all-query-params"); const stripAllQueryParams = inputStripAllQueryParams ? inputStripAllQueryParams.checked : undefined; - const inputStripQueryParamsForDomains = document.getElementById('strip-query-params-for-domains'); - const stripQueryParamsForDomainsValue = inputStripQueryParamsForDomains ? inputStripQueryParamsForDomains.value.trim() : ''; - const stripQueryParamsForDomains = stripQueryParamsForDomainsValue ? stripQueryParamsForDomainsValue.split(',').map(d => d.trim()).filter(d => d) : undefined; + const inputStripQueryParamsForDomains = document.getElementById("strip-query-params-for-domains"); + const stripQueryParamsForDomainsValue = inputStripQueryParamsForDomains ? inputStripQueryParamsForDomains.value.trim() : ""; + const stripQueryParamsForDomains = stripQueryParamsForDomainsValue ? stripQueryParamsForDomainsValue.split(",").map(d => d.trim()).filter(d => d) : undefined; - const inputStripQueryParams = document.getElementById('strip-query-params'); - const stripQueryParamsValue = inputStripQueryParams ? inputStripQueryParams.value.trim() : ''; - const stripQueryParams = stripQueryParamsValue ? stripQueryParamsValue.split(',').map(p => p.trim()).filter(p => p) : undefined; + const inputStripQueryParams = document.getElementById("strip-query-params"); + const stripQueryParamsValue = inputStripQueryParams ? inputStripQueryParams.value.trim() : ""; + const stripQueryParams = stripQueryParamsValue ? stripQueryParamsValue.split(",").map(p => p.trim()).filter(p => p) : undefined; - const inputStripFragments = document.getElementById('strip-fragments'); + const inputStripFragments = document.getElementById("strip-fragments"); const stripFragments = inputStripFragments ? inputStripFragments.checked : undefined; + // IAB Taxonomy Filtering Option + const inputEnableFiltering = document.getElementById("enable-iab-filtering"); + const enableIabFiltering = inputEnableFiltering ? inputEnableFiltering.checked : false; + + // Build iabTaxonomyFilters object only if filtering is enabled + const iabTaxonomyFilters = enableIabFiltering ? { + ContentTier1: { limit: 1, threshold: 0.1 }, + ContentTier2: { limit: 2, threshold: 0.1 }, + ContentTier3: { limit: 3, threshold: 0.15 }, + AudienceTier3: { limit: 3, threshold: 0.2 }, + AudienceTier4: { limit: 5, threshold: 0.2 }, + AudienceTier5: { limit: 7, threshold: 0.3 }, + } : undefined; + pbjs.que.push(function () { pbjs.setConfig({ debug: true, @@ -155,10 +173,12 @@ websiteToAnalyseUrl, iabContentTaxonomyVersion, enableCache, + enableOrtb25Fields, stripAllQueryParams, stripQueryParamsForDomains, stripQueryParams, - stripFragments + stripFragments, + iabTaxonomyFilters, } } ] @@ -185,7 +205,7 @@

Basic Prebid.js Example using Neuwo Rtd Provider

- Looks like you're not following the testing environment setup, try accessing + Looks like you"re not following the testing environment setup, try accessing http://localhost:9999/integrationExamples/gpt/neuwoRtdProvider_example.html @@ -215,12 +235,14 @@

Neuwo Rtd Provider Configuration

- +

IAB Content Taxonomy Options

- +

Cache Options

@@ -231,6 +253,14 @@

Cache Options

+

OpenRTB 2.5 Category Fields

+
+ +
+

URL Cleaning Options

- +
- +
+

IAB Taxonomy Filtering Options

+
+ +
+ When enabled, uses these hardcoded filters:
+ • ContentTier1: top 1 (≥10% relevance)
+ • ContentTier2: top 2 (≥10% relevance)
+ • ContentTier3: top 3 (≥15% relevance)
+ • AudienceTier3: top 3 (≥20% relevance)
+ • AudienceTier4: top 5 (≥20% relevance)
+ • AudienceTier5: top 7 (≥30% relevance) +
+
+ @@ -259,10 +309,10 @@

Ad Examples

Div-1

-
- Ad spot div-1: This content will be replaced by prebid.js and/or related components once you click @@ -272,10 +322,10 @@

Div-1

Div-2

-
- Ad spot div-2: This content will be replaced by prebid.js and/or related components once you click @@ -286,82 +336,327 @@

Div-2

Neuwo Data in Bid Request

-

The retrieved data from Neuwo API is injected into the bid request as OpenRTB (ORTB2)`site.content.data` and - `user.data`. Full bid request can be inspected in Developer Tools Console under +

The retrieved data from Neuwo API is injected into the bid request as OpenRTB (ORTB2) + site.content.data and + user.data. Full bid request can be inspected in Developer Tools Console under INFO: NeuwoRTDModule injectIabCategories: post-injection bidsConfig

+

Neuwo Site Content Data

+
No data yet. Click "Update" to fetch data.
+

Neuwo User Data

+
No data yet. Click "Update" to fetch data.
+

Neuwo OpenRTB 2.5 Category Fields (IAB Content Taxonomy 1.0) Data

+
No data yet. Click "Update" to fetch data (requires enableOrtb25Fields and /v1/iab endpoint).
+
+ +
+

Accessing Neuwo Data in JavaScript

+

Listen to the bidRequested event to access the enriched ORTB2 data:

+
+pbjs.onEvent("bidRequested", function(bidRequest) {
+    const ortb2 = bidRequest.ortb2;
+    const neuwoSiteData = ortb2?.site?.content?.data?.find(d => d.name === "www.neuwo.ai");
+    const neuwoUserData = ortb2?.user?.data?.find(d => d.name === "www.neuwo.ai");
+    console.log("Neuwo data:", { siteContent: neuwoSiteData, user: neuwoUserData });
+});
+        
+

After clicking "Update", the Neuwo data is stored in the global neuwoData variable. Open + Developer Tools Console to see the logged data.

+

Note: Event timing tests for multiple Prebid.js events (auctionInit, bidRequested, + beforeBidderHttp, bidResponse, auctionEnd) are available in the page source code but are commented out. To + enable them, uncomment the timing test section in the JavaScript code.

+
+ +
+

For more information about Neuwo RTD Module configuration and accessing data retrieved from Neuwo API, see modules/neuwoRtdProvider.md.

+ + + + + + + +

Prebid Test Bidder Example

+
Banner ad
+ + + diff --git a/libraries/adkernelUtils/adkernelUtils.js b/libraries/adkernelUtils/adkernelUtils.js index 0b2d48f3824..8dfae13010e 100644 --- a/libraries/adkernelUtils/adkernelUtils.js +++ b/libraries/adkernelUtils/adkernelUtils.js @@ -2,7 +2,7 @@ export function getBidFloor(bid, mediaType, sizes) { var floor; var size = sizes.length === 1 ? sizes[0] : '*'; if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: 'USD', mediaType, size}); + const floorInfo = bid.getFloor({ currency: 'USD', mediaType, size }); if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { floor = parseFloat(floorInfo.floor); } diff --git a/libraries/adrelevantisUtils/bidderUtils.js b/libraries/adrelevantisUtils/bidderUtils.js index 04396e76964..70a28a7e65a 100644 --- a/libraries/adrelevantisUtils/bidderUtils.js +++ b/libraries/adrelevantisUtils/bidderUtils.js @@ -1,4 +1,4 @@ -import {isFn, isPlainObject} from '../../src/utils.js'; +import { isFn, isPlainObject } from '../../src/utils.js'; export function hasUserInfo(bid) { return !!(bid.params && bid.params.user); @@ -15,9 +15,9 @@ export function hasAppId(bid) { export function addUserId(eids, id, source, rti) { if (id) { if (rti) { - eids.push({source, id, rti_partner: rti}); + eids.push({ source, id, rti_partner: rti }); } else { - eids.push({source, id}); + eids.push({ source, id }); } } return eids; diff --git a/libraries/adtelligentUtils/adtelligentUtils.js b/libraries/adtelligentUtils/adtelligentUtils.js index 9769102ed69..8b7a659c862 100644 --- a/libraries/adtelligentUtils/adtelligentUtils.js +++ b/libraries/adtelligentUtils/adtelligentUtils.js @@ -1,6 +1,6 @@ -import {deepAccess, isArray} from '../../src/utils.js'; +import { deepAccess, isArray } from '../../src/utils.js'; import { config } from '../../src/config.js'; -import {BANNER, VIDEO} from '../../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../../src/mediaTypes.js'; export const supportedMediaTypes = [VIDEO, BANNER] diff --git a/libraries/advangUtils/index.js b/libraries/advangUtils/index.js index 7d869cef9e1..aab9c2b6e27 100644 --- a/libraries/advangUtils/index.js +++ b/libraries/advangUtils/index.js @@ -87,7 +87,7 @@ export function getFirstSize(sizes) { export function parseSizes(sizes) { return parseSizesInput(sizes).map(size => { - const [ width, height ] = size.split('x'); + const [width, height] = size.split('x'); return { w: parseInt(width, 10) || undefined, h: parseInt(height, 10) || undefined @@ -108,7 +108,7 @@ export function getTopWindowReferrer(bidderRequest) { } export function getTopWindowLocation(bidderRequest) { - return parseUrl(bidderRequest?.refererInfo?.page, {decodeSearchAsString: true}); + return parseUrl(bidderRequest?.refererInfo?.page, { decodeSearchAsString: true }); } export function getVideoTargetingParams(bid, VIDEO_TARGETING) { @@ -117,12 +117,12 @@ export function getVideoTargetingParams(bid, VIDEO_TARGETING) { Object.keys(Object(bid.mediaTypes.video)) .filter(key => !excludeProps.includes(key)) .forEach(key => { - result[ key ] = bid.mediaTypes.video[ key ]; + result[key] = bid.mediaTypes.video[key]; }); Object.keys(Object(bid.params.video)) .filter(key => VIDEO_TARGETING.includes(key)) .forEach(key => { - result[ key ] = bid.params.video[ key ]; + result[key] = bid.params.video[key]; }); return result; } @@ -215,13 +215,13 @@ export function createRequestData(bid, bidderRequest, isVideo, getBidParam, getS } if (coppa) { - o.regs.ext = {'coppa': 1}; + o.regs.ext = { 'coppa': 1 }; } if (bidderRequest && bidderRequest.gdprConsent) { const { gdprApplies, consentString } = bidderRequest.gdprConsent; - o.regs.ext = {'gdpr': gdprApplies ? 1 : 0}; - o.user.ext = {'consent': consentString}; + o.regs.ext = { 'gdpr': gdprApplies ? 1 : 0 }; + o.user.ext = { 'consent': consentString }; } return o; diff --git a/libraries/analyticsAdapter/AnalyticsAdapter.ts b/libraries/analyticsAdapter/AnalyticsAdapter.ts index fd6cc601442..0cf77d6ed5c 100644 --- a/libraries/analyticsAdapter/AnalyticsAdapter.ts +++ b/libraries/analyticsAdapter/AnalyticsAdapter.ts @@ -1,8 +1,8 @@ import { EVENTS } from '../../src/constants.js'; -import {ajax} from '../../src/ajax.js'; -import {logError, logMessage} from '../../src/utils.js'; +import { ajax } from '../../src/ajax.js'; +import { logError, logMessage } from '../../src/utils.js'; import * as events from '../../src/events.js'; -import {config} from '../../src/config.js'; +import { config } from '../../src/config.js'; export const _internal = { ajax @@ -30,7 +30,7 @@ export function setLabels(internalLabels) { allLabels = combineLabels(); }; -const combineLabels = () => Object.values(labels).reduce((acc, curr) => ({...acc, ...curr}), {}); +const combineLabels = () => Object.values(labels).reduce((acc, curr) => ({ ...acc, ...curr }), {}); export const DEFAULT_INCLUDE_EVENTS = Object.values(EVENTS) .filter(ev => ev !== EVENTS.AUCTION_DEBUG); @@ -146,7 +146,7 @@ export default function AnalyticsAdapter({ u }); function _track(arg) { - const {eventType, args} = arg; + const { eventType, args } = arg; if (this.getAdapterType() === BUNDLE) { (window[global] as any)(handler, eventType, args); } @@ -160,7 +160,7 @@ export default function AnalyticsAdapter({ u _internal.ajax(url, callback, JSON.stringify({ eventType, args, labels: allLabels })); } - function _enqueue({eventType, args}) { + function _enqueue({ eventType, args }) { queue.push(() => { if (Object.keys(allLabels || []).length > 0) { args = { @@ -168,7 +168,7 @@ export default function AnalyticsAdapter({ u ...args, } } - this.track({eventType, labels: allLabels, args}); + this.track({ eventType, labels: allLabels, args }); }); emptyQueue(); } @@ -184,7 +184,7 @@ export default function AnalyticsAdapter({ u if (sampled) { const trackedEvents: Set = (() => { - const {includeEvents = DEFAULT_INCLUDE_EVENTS, excludeEvents = []} = (config || {}); + const { includeEvents = DEFAULT_INCLUDE_EVENTS, excludeEvents = [] } = (config || {}); return new Set( Object.values(EVENTS) .filter(ev => includeEvents.includes(ev)) @@ -206,7 +206,7 @@ export default function AnalyticsAdapter({ u handlers = Object.fromEntries( Array.from(trackedEvents) .map((ev) => { - const handler = (args) => this.enqueue({eventType: ev, args}); + const handler = (args) => this.enqueue({ eventType: ev, args }); events.on(ev, handler); return [ev, handler]; }) diff --git a/libraries/appnexusUtils/anKeywords.js b/libraries/appnexusUtils/anKeywords.js index 8246b1e4f65..63f7df423f6 100644 --- a/libraries/appnexusUtils/anKeywords.js +++ b/libraries/appnexusUtils/anKeywords.js @@ -1,6 +1,6 @@ -import {_each, deepAccess, isArray, isNumber, isStr, mergeDeep, logWarn} from '../../src/utils.js'; -import {getAllOrtbKeywords} from '../keywords/keywords.js'; -import {CLIENT_SECTIONS} from '../../src/fpd/oneClient.js'; +import { _each, deepAccess, isArray, isNumber, isStr, mergeDeep, logWarn } from '../../src/utils.js'; +import { getAllOrtbKeywords } from '../keywords/keywords.js'; +import { CLIENT_SECTIONS } from '../../src/fpd/oneClient.js'; const ORTB_SEGTAX_KEY_MAP = { 526: '1plusX', @@ -56,7 +56,7 @@ export function transformBidderParamKeywords(keywords, paramName = 'keywords') { } // unsuported types - don't send a key } v = v.filter(kw => kw !== '') - const entry = {key: k} + const entry = { key: k } if (v.length > 0) { entry.value = v; } diff --git a/libraries/appnexusUtils/anUtils.js b/libraries/appnexusUtils/anUtils.js index 6a87625162b..191512f2fea 100644 --- a/libraries/appnexusUtils/anUtils.js +++ b/libraries/appnexusUtils/anUtils.js @@ -2,7 +2,7 @@ * Converts a string value in camel-case to underscore eg 'placementId' becomes 'placement_id' * @param {string} value string value to convert */ -import {deepClone, isPlainObject} from '../../src/utils.js'; +import { deepClone, isPlainObject } from '../../src/utils.js'; export function convertCamelToUnderscore(value) { return value.replace(/(?:^|\.?)([A-Z])/g, function (x, y) { diff --git a/libraries/audUtils/bidderUtils.js b/libraries/audUtils/bidderUtils.js index 18e8e669a71..660f871ab8a 100644 --- a/libraries/audUtils/bidderUtils.js +++ b/libraries/audUtils/bidderUtils.js @@ -160,7 +160,7 @@ const getSiteDetails = (bidderRequest) => { page = bidderRequest.refererInfo.page; name = bidderRequest.refererInfo.domain; } - return {page: page, name: name}; + return { page: page, name: name }; } // Function to build the user object const getUserDetails = (bidReq) => { diff --git a/libraries/braveUtils/buildAndInterpret.js b/libraries/braveUtils/buildAndInterpret.js index 7974b1f079e..bfcb5d6c2dd 100644 --- a/libraries/braveUtils/buildAndInterpret.js +++ b/libraries/braveUtils/buildAndInterpret.js @@ -1,5 +1,5 @@ import { isEmpty } from '../../src/utils.js'; -import {config} from '../../src/config.js'; +import { config } from '../../src/config.js'; import { createNativeRequest, createBannerRequest, createVideoRequest, getFloor, prepareSite, prepareConsents, prepareEids } from './index.js'; import { convertOrtbRequestToProprietaryNative } from '../../src/native.js'; diff --git a/libraries/braveUtils/index.js b/libraries/braveUtils/index.js index fe9d68107cb..34742f41ed8 100644 --- a/libraries/braveUtils/index.js +++ b/libraries/braveUtils/index.js @@ -66,7 +66,7 @@ export function createBannerRequest(br) { * @returns {object} The video request object */ export function createVideoRequest(br) { - const videoObj = {...br.mediaTypes.video, id: br.transactionId}; + const videoObj = { ...br.mediaTypes.video, id: br.transactionId }; if (videoObj.playerSize) { const size = Array.isArray(videoObj.playerSize[0]) ? videoObj.playerSize[0] : videoObj.playerSize; diff --git a/libraries/cmp/cmpClient.js b/libraries/cmp/cmpClient.js index 9e7e225ddb4..1ad691b824c 100644 --- a/libraries/cmp/cmpClient.js +++ b/libraries/cmp/cmpClient.js @@ -1,4 +1,4 @@ -import {PbPromise} from '../../src/utils/promise.js'; +import { PbPromise } from '../../src/utils/promise.js'; /** * @typedef {function} CMPClient @@ -109,7 +109,7 @@ export function cmpClient( } function resolveParams(params) { - params = Object.assign({version: apiVersion}, params); + params = Object.assign({ version: apiVersion }, params); return apiArgs.map(arg => [arg, params[arg]]) } diff --git a/libraries/consentManagement/cmUtils.ts b/libraries/consentManagement/cmUtils.ts index d8012241fc7..44553ed5f06 100644 --- a/libraries/consentManagement/cmUtils.ts +++ b/libraries/consentManagement/cmUtils.ts @@ -1,14 +1,14 @@ -import {timedAuctionHook} from '../../src/utils/perfMetrics.js'; -import {isNumber, isPlainObject, isStr, logError, logInfo, logWarn} from '../../src/utils.js'; -import {ConsentHandler} from '../../src/consentHandler.js'; -import {PbPromise} from '../../src/utils/promise.js'; -import {buildActivityParams} from '../../src/activities/params.js'; -import {getHook} from '../../src/hook.js'; +import { timedAuctionHook } from '../../src/utils/perfMetrics.js'; +import { isNumber, isPlainObject, isStr, logError, logInfo, logWarn } from '../../src/utils.js'; +import { ConsentHandler } from '../../src/consentHandler.js'; +import { PbPromise } from '../../src/utils/promise.js'; +import { buildActivityParams } from '../../src/activities/params.js'; +import { getHook } from '../../src/hook.js'; export function consentManagementHook(name, loadConsentData) { const SEEN = new WeakSet(); return timedAuctionHook(name, function requestBidsHook(fn, reqBidsConfigObj) { - return loadConsentData().then(({consentData, error}) => { + return loadConsentData().then(({ consentData, error }) => { if (error && (!consentData || !SEEN.has(error))) { SEEN.add(error); logWarn(error.message, ...(error.args || [])); @@ -83,14 +83,14 @@ export function lookupConsentData( const consentData = consentDataHandler.getConsentData() ?? (cmpLoaded ? provisionalConsent : getNullConsent()); const message = `timeout waiting for ${cmpLoaded ? 'user action on CMP' : 'CMP to load'}`; consentDataHandler.setConsentData(consentData); - resolve({consentData, error: new Error(`${name} ${message}`)}); + resolve({ consentData, error: new Error(`${name} ${message}`) }); }, timeout); } else { timeoutHandle = null; } } setupCmp(setProvisionalConsent) - .then(() => resolve({consentData: consentDataHandler.getConsentData()}), reject); + .then(() => resolve({ consentData: consentDataHandler.getConsentData() }), reject); cmpTimeout != null && resetTimeout(cmpTimeout); }).finally(() => { timeoutHandle && clearTimeout(timeoutHandle); @@ -153,11 +153,11 @@ export function configParser( let requestBidsHook, cdLoader, staticConsentData; function attachActivityParams(next, params) { - return next(Object.assign({[`${namespace}Consent`]: consentDataHandler.getConsentData()}, params)); + return next(Object.assign({ [`${namespace}Consent`]: consentDataHandler.getConsentData() }, params)); } function loadConsentData() { - return cdLoader().then(({error}) => ({error, consentData: consentDataHandler.getConsentData()})) + return cdLoader().then(({ error }) => ({ error, consentData: consentDataHandler.getConsentData() })) } function activate() { @@ -171,8 +171,8 @@ export function configParser( function reset() { if (requestBidsHook != null) { - getHook('requestBids').getHooks({hook: requestBidsHook}).remove(); - buildActivityParams.getHooks({hook: attachActivityParams}).remove(); + getHook('requestBids').getHooks({ hook: requestBidsHook }).remove(); + buildActivityParams.getHooks({ hook: attachActivityParams }).remove(); requestBidsHook = null; logInfo(`${displayName} consentManagement module has been deactivated...`); } diff --git a/libraries/cookieSync/cookieSync.js b/libraries/cookieSync/cookieSync.js index c51d61e240b..13e672005eb 100644 --- a/libraries/cookieSync/cookieSync.js +++ b/libraries/cookieSync/cookieSync.js @@ -2,7 +2,7 @@ import { getStorageManager } from '../../src/storageManager.js'; const COOKIE_KEY_MGUID = '__mguid_'; export function cookieSync(syncOptions, gdprConsent, uspConsent, bidderCode, cookieOrigin, ckIframeUrl, cookieTime) { - const storage = getStorageManager({bidderCode: bidderCode}); + const storage = getStorageManager({ bidderCode: bidderCode }); const origin = encodeURIComponent(location.origin || `https://${location.host}`); let syncParamUrl = `dm=${origin}`; diff --git a/libraries/currencyUtils/currency.js b/libraries/currencyUtils/currency.js index 924f8f200d8..c5a23d34e36 100644 --- a/libraries/currencyUtils/currency.js +++ b/libraries/currencyUtils/currency.js @@ -1,5 +1,5 @@ -import {getGlobal} from '../../src/prebidGlobal.js'; -import {keyCompare} from '../../src/utils/reducers.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; +import { keyCompare } from '../../src/utils/reducers.js'; /** * Attempt to convert `amount` from the currency `fromCur` to the currency `toCur`. diff --git a/libraries/devicePixelRatio/devicePixelRatio.js b/libraries/devicePixelRatio/devicePixelRatio.js index 8bfe23bcb3d..f6e9d85cac7 100644 --- a/libraries/devicePixelRatio/devicePixelRatio.js +++ b/libraries/devicePixelRatio/devicePixelRatio.js @@ -1,14 +1,10 @@ -import {canAccessWindowTop, internal as utilsInternals} from '../../src/utils.js'; - -function getFallbackWindow(win) { - if (win) { - return win; - } - - return canAccessWindowTop() ? utilsInternals.getWindowTop() : utilsInternals.getWindowSelf(); -} +import { isFingerprintingApiDisabled } from '../fingerprinting/fingerprinting.js'; +import { getFallbackWindow } from '../../src/utils.js'; export function getDevicePixelRatio(win) { + if (isFingerprintingApiDisabled('devicepixelratio')) { + return 1; + } try { return getFallbackWindow(win).devicePixelRatio; } catch (e) { diff --git a/libraries/dfpUtils/dfpUtils.js b/libraries/dfpUtils/dfpUtils.js index 4b957eb4999..bad6c05b356 100644 --- a/libraries/dfpUtils/dfpUtils.js +++ b/libraries/dfpUtils/dfpUtils.js @@ -1,4 +1,4 @@ -import {gdprDataHandler} from '../../src/consentHandler.js'; +import { gdprDataHandler } from '../../src/consentHandler.js'; /** Safe defaults which work on pretty much all video calls. */ export const DEFAULT_DFP_PARAMS = { diff --git a/libraries/dspxUtils/bidderUtils.js b/libraries/dspxUtils/bidderUtils.js index 29e44313a62..b238d9dc2eb 100644 --- a/libraries/dspxUtils/bidderUtils.js +++ b/libraries/dspxUtils/bidderUtils.js @@ -1,5 +1,5 @@ import { BANNER, VIDEO } from '../../src/mediaTypes.js'; -import {deepAccess, isArray, isEmptyStr, isFn} from '../../src/utils.js'; +import { deepAccess, isArray, isEmptyStr, isFn } from '../../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidderRequest} BidderRequest * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/libraries/dxUtils/common.js b/libraries/dxUtils/common.js index 3e5e43de0d6..ac0ce6e4433 100644 --- a/libraries/dxUtils/common.js +++ b/libraries/dxUtils/common.js @@ -6,9 +6,9 @@ import { deepSetValue, mergeDeep } from '../../src/utils.js'; -import {BANNER, VIDEO} from '../../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../../src/mediaTypes.js'; import { Renderer } from '../../src/Renderer.js'; -import {ortbConverter} from '../ortbConverter/converter.js'; +import { ortbConverter } from '../ortbConverter/converter.js'; /** * @typedef {import('../../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -67,7 +67,7 @@ export function createDxConverter(config) { }, bidResponse(buildBidResponse, bid, context) { let resMediaType; - const {bidRequest} = context; + const { bidRequest } = context; if (bid.adm && bid.adm.trim().startsWith(' String(item).toLowerCase() === apiName.toLowerCase()); +} diff --git a/libraries/gamUtils/gamUtils.js b/libraries/gamUtils/gamUtils.js index f1c4f1c6554..3c2590271e0 100644 --- a/libraries/gamUtils/gamUtils.js +++ b/libraries/gamUtils/gamUtils.js @@ -1 +1 @@ -export {DEFAULT_DFP_PARAMS as DEFAULT_GAM_PARAMS, DFP_ENDPOINT as GAM_ENDPOINT, gdprParams} from '../dfpUtils/dfpUtils.js'; +export { DEFAULT_DFP_PARAMS as DEFAULT_GAM_PARAMS, DFP_ENDPOINT as GAM_ENDPOINT, gdprParams } from '../dfpUtils/dfpUtils.js'; diff --git a/libraries/gptUtils/gptUtils.js b/libraries/gptUtils/gptUtils.js index 17ca64483ab..fef9aba37a4 100644 --- a/libraries/gptUtils/gptUtils.js +++ b/libraries/gptUtils/gptUtils.js @@ -1,5 +1,5 @@ import { CLIENT_SECTIONS } from '../../src/fpd/oneClient.js'; -import {compareCodeAndSlot, deepAccess, isGptPubadsDefined, uniques, isEmpty} from '../../src/utils.js'; +import { compareCodeAndSlot, deepAccess, isGptPubadsDefined, uniques, isEmpty } from '../../src/utils.js'; const slotInfoCache = new Map(); @@ -21,7 +21,7 @@ export function isSlotMatchingAdUnitCode(adUnitCode) { */ export function setKeyValue(key, value) { if (!key || typeof key !== 'string') return false; - window.googletag = window.googletag || {cmd: []}; + window.googletag = window.googletag || { cmd: [] }; window.googletag.cmd = window.googletag.cmd || []; window.googletag.cmd.push(() => { window.googletag.pubads().setTargeting(key, value); @@ -65,7 +65,7 @@ export function getSignals(fpd) { const signals = Object.entries({ [taxonomies[0]]: getSegments(fpd, ['user.data'], 4), [taxonomies[1]]: getSegments(fpd, CLIENT_SECTIONS.map(section => `${section}.content.data`), 6) - }).map(([taxonomy, values]) => values.length ? {taxonomy, values} : null) + }).map(([taxonomy, values]) => values.length ? { taxonomy, values } : null) .filter(ob => ob); return signals; diff --git a/libraries/greedy/greedyPromise.js b/libraries/greedy/greedyPromise.js index 74b105297dc..5d7713424db 100644 --- a/libraries/greedy/greedyPromise.js +++ b/libraries/greedy/greedyPromise.js @@ -101,7 +101,7 @@ export class GreedyPromise { return new this((resolve) => { const res = []; this.#collect(promises, (success, val, i) => { - res[i] = success ? {status: 'fulfilled', value: val} : {status: 'rejected', reason: val}; + res[i] = success ? { status: 'fulfilled', value: val } : { status: 'rejected', reason: val }; }, () => resolve(res)) }) } diff --git a/libraries/hybridVoxUtils/index.js b/libraries/hybridVoxUtils/index.js index f9f5c21b1cb..5f4de42e43c 100644 --- a/libraries/hybridVoxUtils/index.js +++ b/libraries/hybridVoxUtils/index.js @@ -1,6 +1,6 @@ // Utility functions extracted by codex bot -import {Renderer} from '../../src/Renderer.js'; -import {logWarn, deepAccess, isArray} from '../../src/utils.js'; +import { Renderer } from '../../src/Renderer.js'; +import { logWarn, deepAccess, isArray } from '../../src/utils.js'; export const outstreamRender = bid => { bid.renderer.push(() => { diff --git a/libraries/intentIqUtils/storageUtils.js b/libraries/intentIqUtils/storageUtils.js index 338333ef3d1..a15e09bbac2 100644 --- a/libraries/intentIqUtils/storageUtils.js +++ b/libraries/intentIqUtils/storageUtils.js @@ -1,12 +1,12 @@ -import {logError, logInfo} from '../../src/utils.js'; -import {SUPPORTED_TYPES, FIRST_PARTY_KEY} from '../../libraries/intentIqConstants/intentIqConstants.js'; -import {getStorageManager} from '../../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../../src/activities/modules.js'; +import { logError, logInfo } from '../../src/utils.js'; +import { SUPPORTED_TYPES, FIRST_PARTY_KEY } from '../../libraries/intentIqConstants/intentIqConstants.js'; +import { getStorageManager } from '../../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../../src/activities/modules.js'; const MODULE_NAME = 'intentIqId'; const PCID_EXPIRY = 365; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** * Read data from local storage or cookie based on allowed storage types. diff --git a/libraries/interpretResponseUtils/index.js b/libraries/interpretResponseUtils/index.js index 6d081e4c272..6021d2fdbe5 100644 --- a/libraries/interpretResponseUtils/index.js +++ b/libraries/interpretResponseUtils/index.js @@ -1,6 +1,6 @@ -import {logError} from '../../src/utils.js'; +import { logError } from '../../src/utils.js'; -export function interpretResponseUtil(serverResponse, {bidderRequest}, eachBidCallback) { +export function interpretResponseUtil(serverResponse, { bidderRequest }, eachBidCallback) { const bids = []; if (!serverResponse.body || serverResponse.body.error) { let errorMessage = `in response for ${bidderRequest.bidderCode} adapter`; diff --git a/libraries/keywords/keywords.js b/libraries/keywords/keywords.js index b317bcf0c6b..04912a84b5b 100644 --- a/libraries/keywords/keywords.js +++ b/libraries/keywords/keywords.js @@ -1,5 +1,5 @@ -import {CLIENT_SECTIONS} from '../../src/fpd/oneClient.js'; -import {deepAccess} from '../../src/utils.js'; +import { CLIENT_SECTIONS } from '../../src/fpd/oneClient.js'; +import { deepAccess } from '../../src/utils.js'; const ORTB_KEYWORDS_PATHS = ['user.keywords'].concat( CLIENT_SECTIONS.flatMap((prefix) => ['keywords', 'content.keywords'].map(suffix => `${prefix}.${suffix}`)) diff --git a/libraries/liveIntentId/idSystem.js b/libraries/liveIntentId/idSystem.js index 0ac38feee79..0c8c1739207 100644 --- a/libraries/liveIntentId/idSystem.js +++ b/libraries/liveIntentId/idSystem.js @@ -21,7 +21,7 @@ import { DEFAULT_AJAX_TIMEOUT, MODULE_NAME, composeResult, eids, GVLID, DEFAULT_ const EVENTS_TOPIC = 'pre_lips'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); const calls = { ajaxGet: (url, onSuccess, onError, timeout, headers) => { ajaxBuilder(timeout)( diff --git a/libraries/liveIntentId/shared.js b/libraries/liveIntentId/shared.js index 77ef0f53736..56ce8c3c8cb 100644 --- a/libraries/liveIntentId/shared.js +++ b/libraries/liveIntentId/shared.js @@ -1,5 +1,5 @@ -import {UID1_EIDS} from '../uid1Eids/uid1Eids.js'; -import {UID2_EIDS} from '../uid2Eids/uid2Eids.js'; +import { UID1_EIDS } from '../uid1Eids/uid1Eids.js'; +import { UID2_EIDS } from '../uid2Eids/uid2Eids.js'; import { getRefererInfo } from '../../src/refererDetection.js'; import { isNumber } from '../../src/utils.js' @@ -17,7 +17,7 @@ export function parseRequestedAttributes(overrides) { return Object.entries(config).flatMap(([k, v]) => (typeof v === 'boolean' && v) ? [k] : []); } if (typeof overrides === 'object') { - return createParameterArray({...DEFAULT_REQUESTED_ATTRIBUTES, ...overrides}); + return createParameterArray({ ...DEFAULT_REQUESTED_ATTRIBUTES, ...overrides }); } else { return createParameterArray(DEFAULT_REQUESTED_ATTRIBUTES); } @@ -112,7 +112,7 @@ function composeIdObject(value) { } if (value.thetradedesk) { - result.lipb = {...result.lipb, tdid: value.thetradedesk} + result.lipb = { ...result.lipb, tdid: value.thetradedesk } result.tdid = { 'id': value.thetradedesk, ext: { rtiPartner: 'TDID', provider: getRefererInfo().domain || LI_PROVIDER_DOMAIN } } delete result.lipb.thetradedesk } diff --git a/libraries/medianetUtils/logKeys.js b/libraries/medianetUtils/logKeys.js index 94ddcb82abb..eedc4a726ea 100644 --- a/libraries/medianetUtils/logKeys.js +++ b/libraries/medianetUtils/logKeys.js @@ -43,7 +43,7 @@ export const KeysMap = { AdSlot: [ 'code', 'ext as adext', - 'logged', () => ({[LOG_APPR]: false, [LOG_RA]: false}), + 'logged', () => ({ [LOG_APPR]: false, [LOG_RA]: false }), 'supcrid', (_, __, adUnit) => adUnit.emsCode || adUnit.code, 'ortb2Imp', ], @@ -98,7 +98,7 @@ export const KeysMap = { 'inCurrMul as imul', 'mediaTypes as req_mtype', (mediaTypes) => mediaTypes.join('|'), 'mediaType as res_mtype', - 'mediaType as mtype', (mediaType, __, {mediaTypes}) => mediaType || mediaTypes.join('|'), + 'mediaType as mtype', (mediaType, __, { mediaTypes }) => mediaType || mediaTypes.join('|'), 'ext.seat as ortbseat', 'ext.int_dsp_id as mx_int_dsp_id', 'ext.int_agency_id as mx_int_agency_id', @@ -109,7 +109,7 @@ export const KeysMap = { 'originalRequestId as ogReqId', 'adId as adid', 'originalBidder as og_pvnm', - 'bidderCode as pvnm', (bidderCode, _, {bidder}) => bidderCode || bidder, + 'bidderCode as pvnm', (bidderCode, _, { bidder }) => bidderCode || bidder, 'src', 'originalCpm as ogbdp', 'bdp', (bdp, _, bidObj) => bdp || bidObj.cpm, diff --git a/libraries/medianetUtils/logger.js b/libraries/medianetUtils/logger.js index d3a5dea1551..d3dc46419f4 100644 --- a/libraries/medianetUtils/logger.js +++ b/libraries/medianetUtils/logger.js @@ -23,7 +23,7 @@ export function shouldLogAPPR(auctionData, adUnitId) { // common error logger for medianet analytics and bid adapter export function errorLogger(event, data = undefined, analytics = true) { - const { name, cid, value, relatedData, logData, project } = isPlainObject(event) ? {...event, logData: data} : { name: event, relatedData: data }; + const { name, cid, value, relatedData, logData, project } = isPlainObject(event) ? { ...event, logData: data } : { name: event, relatedData: data }; const refererInfo = mnetGlobals.refererInfo || getRefererInfo(); const errorData = Object.assign({}, { @@ -88,7 +88,7 @@ export function fireAjaxLog(loggingHost, payload, errorData = {}) { ajax(loggingHost, { success: () => undefined, - error: (_, {reason}) => errorLogger(Object.assign(errorData, {name: 'ajax_log_failed', relatedData: reason})).send() + error: (_, { reason }) => errorLogger(Object.assign(errorData, { name: 'ajax_log_failed', relatedData: reason })).send() }, payload, { diff --git a/libraries/medianetUtils/utils.js b/libraries/medianetUtils/utils.js index 667c52e9fb2..800ff80ef99 100644 --- a/libraries/medianetUtils/utils.js +++ b/libraries/medianetUtils/utils.js @@ -1,6 +1,6 @@ import { _map, deepAccess, isFn, isPlainObject, uniques } from '../../src/utils.js'; -import {mnetGlobals} from './constants.js'; -import {getViewportSize} from '../viewport/viewport.js'; +import { mnetGlobals } from './constants.js'; +import { getViewportSize } from '../viewport/viewport.js'; export function findBidObj(list = [], key, value) { return list.find((bid) => { diff --git a/libraries/metadata/metadata.js b/libraries/metadata/metadata.js index dcabc99ac97..59d073de97f 100644 --- a/libraries/metadata/metadata.js +++ b/libraries/metadata/metadata.js @@ -33,8 +33,8 @@ export function metadataRepository() { if (components.length === 0) return null; const disclosures = Object.fromEntries( components - .filter(({disclosureURL}) => disclosureURL != null) - .map(({disclosureURL}) => [disclosureURL, repo.getStorageDisclosure(disclosureURL)]) + .filter(({ disclosureURL }) => disclosureURL != null) + .map(({ disclosureURL }) => [disclosureURL, repo.getStorageDisclosure(disclosureURL)]) ) return { disclosures, diff --git a/libraries/mspa/activityControls.js b/libraries/mspa/activityControls.js index c93748f73c7..ec7100467f4 100644 --- a/libraries/mspa/activityControls.js +++ b/libraries/mspa/activityControls.js @@ -1,12 +1,12 @@ -import {registerActivityControl} from '../../src/activities/rules.js'; +import { registerActivityControl } from '../../src/activities/rules.js'; import { ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD, ACTIVITY_SYNC_USER, ACTIVITY_TRANSMIT_PRECISE_GEO } from '../../src/activities/activities.js'; -import {gppDataHandler} from '../../src/adapterManager.js'; -import {logInfo} from '../../src/utils.js'; +import { gppDataHandler } from '../../src/adapterManager.js'; +import { logInfo } from '../../src/utils.js'; // default interpretation for MSPA consent(s): // https://docs.prebid.org/features/mspa-usnat.html @@ -79,7 +79,7 @@ export const isTransmitUfpdConsentDenied = (() => { })() return function (cd) { - const {cannotBeInScope, mustHaveConsent, allExceptGeo} = sensitiveFlags[cd.Version]; + const { cannotBeInScope, mustHaveConsent, allExceptGeo } = sensitiveFlags[cd.Version]; return isConsentDenied(cd) || // no notice about sensitive data was given sensitiveNoticeIs(cd, 2) || @@ -114,13 +114,13 @@ export function mspaRule(sids, getConsent, denies, applicableSids = () => gppDat if (applicableSids().some(sid => sids.includes(sid))) { const consent = getConsent(); if (consent == null) { - return {allow: false, reason: 'consent data not available'}; + return { allow: false, reason: 'consent data not available' }; } if (![1, 2].includes(consent.Version)) { - return {allow: false, reason: `unsupported consent specification version "${consent.Version}"`} + return { allow: false, reason: `unsupported consent specification version "${consent.Version}"` } } if (denies(consent)) { - return {allow: false}; + return { allow: false }; } } }; diff --git a/libraries/nativeAssetsUtils.js b/libraries/nativeAssetsUtils.js index 9a59716cc68..4f985abaab8 100644 --- a/libraries/nativeAssetsUtils.js +++ b/libraries/nativeAssetsUtils.js @@ -87,9 +87,9 @@ export function buildNativeRequest(nativeParams) { if (nativeParams) { Object.keys(nativeParams).forEach((key) => { if (NATIVE_PARAMS[key]) { - const {name, type, id} = NATIVE_PARAMS[key]; - const assetObj = type ? {type} : {}; - let {len, sizes, required, aspect_ratios: aRatios} = nativeParams[key]; + const { name, type, id } = NATIVE_PARAMS[key]; + const assetObj = type ? { type } : {}; + let { len, sizes, required, aspect_ratios: aRatios } = nativeParams[key]; if (len) { assetObj.len = len; } @@ -105,7 +105,7 @@ export function buildNativeRequest(nativeParams) { assetObj.w = sizes[0]; assetObj.h = sizes[1]; } - const asset = {required: required ? 1 : 0, id}; + const asset = { required: required ? 1 : 0, id }; asset[name] = assetObj; assets.push(asset); } @@ -123,7 +123,7 @@ export function buildNativeRequest(nativeParams) { } export function parseNativeResponse(native) { - const {assets, link, imptrackers, jstracker} = native; + const { assets, link, imptrackers, jstracker } = native; const result = { clickUrl: link.url, clickTrackers: link.clicktrackers || [], @@ -132,7 +132,7 @@ export function parseNativeResponse(native) { }; (assets || []).forEach((asset) => { - const {id, img, data, title} = asset; + const { id, img, data, title } = asset; const key = NATIVE_ID_MAP[id]; if (key) { if (!isEmpty(title)) { diff --git a/libraries/nexx360Utils/index.ts b/libraries/nexx360Utils/index.ts index 0b8ed3fd719..f0bb2ce39ea 100644 --- a/libraries/nexx360Utils/index.ts +++ b/libraries/nexx360Utils/index.ts @@ -1,5 +1,5 @@ import { deepAccess, deepSetValue, generateUUID, logInfo } from '../../src/utils.js'; -import {Renderer} from '../../src/Renderer.js'; +import { Renderer } from '../../src/Renderer.js'; import { getCurrencyFromBidderRequest } from '../ortb2Utils/currency.js'; import { INSTREAM, OUTSTREAM } from '../../src/video.js'; import { BANNER, MediaType, NATIVE, VIDEO } from '../../src/mediaTypes.js'; diff --git a/libraries/objectGuard/objectGuard.js b/libraries/objectGuard/objectGuard.js index 973e56aad5f..4fbd58080f9 100644 --- a/libraries/objectGuard/objectGuard.js +++ b/libraries/objectGuard/objectGuard.js @@ -1,5 +1,5 @@ -import {isData, sessionedApplies} from '../../src/activities/redactor.js'; -import {deepEqual, logWarn} from '../../src/utils.js'; +import { isData, sessionedApplies } from '../../src/activities/redactor.js'; +import { deepEqual, logWarn } from '../../src/utils.js'; /** * @typedef {import('../src/activities/redactor.js').TransformationRuleDef} TransformationRuleDef @@ -139,20 +139,46 @@ export function objectGuard(rules) { return true; } + const TARGET = Symbol('TARGET'); + function mkGuard(obj, tree, final, applies, cache = new WeakMap()) { // If this object is already proxied, return the cached proxy if (cache.has(obj)) { return cache.get(obj); } + /** + * Dereference (possibly nested) proxies to their underlying objects. + * + * This is to accommodate usage patterns like: + * + * guardedObject.property = [...guardedObject.property, additionalData]; + * + * where the `set` proxy trap would get an already proxied object as argument. + */ + function deref(obj, visited = new Set()) { + if (cache.has(obj?.[TARGET])) return obj[TARGET]; + if (obj == null || typeof obj !== 'object') return obj; + if (visited.has(obj)) return obj; + visited.add(obj); + Object.keys(obj).forEach(k => { + const sub = deref(obj[k], visited); + if (sub !== obj[k]) { + obj[k] = sub; + } + }) + return obj; + } + const proxy = new Proxy(obj, { get(target, prop, receiver) { + if (prop === TARGET) return target; const val = Reflect.get(target, prop, receiver); if (final && val != null && typeof val === 'object') { // a parent property has write protect rules, keep guarding return mkGuard(val, tree, final, applies, cache) } else if (tree.children?.hasOwnProperty(prop)) { - const {children, hasWP} = tree.children[prop]; + const { children, hasWP } = tree.children[prop]; if (isData(val)) { // if this property has redact rules, apply them const rule = getRedactRule(tree.children[prop]); @@ -175,6 +201,7 @@ export function objectGuard(rules) { return true; } } + newValue = deref(newValue); if (tree.children?.hasOwnProperty(prop)) { // apply all (possibly nested) write protect rules const curValue = Reflect.get(target, prop, receiver); diff --git a/libraries/objectGuard/ortbGuard.js b/libraries/objectGuard/ortbGuard.js index 324c7976ab1..7587975ac06 100644 --- a/libraries/objectGuard/ortbGuard.js +++ b/libraries/objectGuard/ortbGuard.js @@ -1,13 +1,13 @@ -import {isActivityAllowed} from '../../src/activities/rules.js'; -import {ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD} from '../../src/activities/activities.js'; +import { isActivityAllowed } from '../../src/activities/rules.js'; +import { ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD } from '../../src/activities/activities.js'; import { appliesWhenActivityDenied, ortb2TransmitRules, ORTB_EIDS_PATHS, ORTB_UFPD_PATHS } from '../../src/activities/redactor.js'; -import {objectGuard, writeProtectRule} from './objectGuard.js'; -import {logError} from '../../src/utils.js'; +import { objectGuard, writeProtectRule } from './objectGuard.js'; +import { logError } from '../../src/utils.js'; function ortb2EnrichRules(isAllowed = isActivityAllowed) { return [ @@ -70,7 +70,7 @@ export function ortb2FragmentsGuardFactory(guardOrtb2 = ortb2Guard) { {}, Object.fromEntries( // disallow overwriting of the top level `global` / `bidder` - Object.entries(guard).map(([prop, obj]) => [prop, {get: () => obj}]) + Object.entries(guard).map(([prop, obj]) => [prop, { get: () => obj }]) ) ) } diff --git a/libraries/omsUtils/index.js b/libraries/omsUtils/index.js index b2523749080..421abeb8801 100644 --- a/libraries/omsUtils/index.js +++ b/libraries/omsUtils/index.js @@ -1,4 +1,4 @@ -import {getWindowSelf, getWindowTop, isFn, isPlainObject} from '../../src/utils.js'; +import { createTrackPixelHtml, getWindowSelf, getWindowTop, isArray, isFn, isPlainObject } from '../../src/utils.js'; export function getBidFloor(bid) { if (!isFn(bid.getFloor)) { @@ -21,3 +21,28 @@ export function isIframe() { return true; } } + +export function getProcessedSizes(sizes = []) { + const bidSizes = ((isArray(sizes) && isArray(sizes[0])) ? sizes : [sizes]).filter(size => isArray(size)); + return bidSizes.map(size => ({ w: parseInt(size[0], 10), h: parseInt(size[1], 10) })); +} + +export function getDeviceType(ua = navigator.userAgent, sua) { + if (sua?.mobile || (/(ios|ipod|ipad|iphone|android)/i).test(ua)) { + return 1; + } + + if ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(ua)) { + return 3; + } + + return 2; +} + +export function getAdMarkup(bid) { + let adm = bid.adm; + if ('nurl' in bid) { + adm += createTrackPixelHtml(bid.nurl); + } + return adm; +} diff --git a/libraries/omsUtils/viewability.js b/libraries/omsUtils/viewability.js new file mode 100644 index 00000000000..6d4b12c5e94 --- /dev/null +++ b/libraries/omsUtils/viewability.js @@ -0,0 +1,19 @@ +import { getWindowTop } from '../../src/utils.js'; +import { percentInView } from '../percentInView/percentInView.js'; +import { getMinSize } from '../sizeUtils/sizeUtils.js'; +import { isIframe } from './index.js'; + +export function getRoundedViewability(adUnitCode, processedSizes) { + const element = document.getElementById(adUnitCode); + const minSize = getMinSize(processedSizes); + const viewabilityAmount = isViewabilityMeasurable(element) ? getViewability(element, minSize) : 'na'; + return isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); +} + +function isViewabilityMeasurable(element) { + return !isIframe() && element !== null; +} + +function getViewability(element, { w, h } = {}) { + return getWindowTop().document.visibilityState === 'visible' ? percentInView(element, { w, h }) : 0; +} diff --git a/libraries/ortb2.5StrictTranslator/spec.js b/libraries/ortb2.5StrictTranslator/spec.js index 0ffb17a2e72..26be3f5b816 100644 --- a/libraries/ortb2.5StrictTranslator/spec.js +++ b/libraries/ortb2.5StrictTranslator/spec.js @@ -1,4 +1,4 @@ -import {Arr, extend, ID, IntEnum, Named, Obj} from './dsl.js'; +import { Arr, extend, ID, IntEnum, Named, Obj } from './dsl.js'; const CatDomain = Named[extend](['cat', 'domain']); const Segment = Named[extend](['value']); diff --git a/libraries/ortb2.5StrictTranslator/translator.js b/libraries/ortb2.5StrictTranslator/translator.js index c6f651e2476..7704bee0b92 100644 --- a/libraries/ortb2.5StrictTranslator/translator.js +++ b/libraries/ortb2.5StrictTranslator/translator.js @@ -1,6 +1,6 @@ -import {BidRequest} from './spec.js'; -import {logWarn} from '../../src/utils.js'; -import {toOrtb25} from '../ortb2.5Translator/translator.js'; +import { BidRequest } from './spec.js'; +import { logWarn } from '../../src/utils.js'; +import { toOrtb25 } from '../ortb2.5Translator/translator.js'; function deleteField(errno, path, obj, field, value) { logWarn(`${path} is not valid ORTB 2.5, field will be removed from request:`, value); diff --git a/libraries/ortb2.5Translator/translator.js b/libraries/ortb2.5Translator/translator.js index 1634d6584d0..f65de19b306 100644 --- a/libraries/ortb2.5Translator/translator.js +++ b/libraries/ortb2.5Translator/translator.js @@ -1,4 +1,4 @@ -import {deepAccess, deepSetValue, logError} from '../../src/utils.js'; +import { deepAccess, deepSetValue, logError } from '../../src/utils.js'; export const EXT_PROMOTIONS = [ 'device.sua', diff --git a/libraries/ortbConverter/README.md b/libraries/ortbConverter/README.md index c67533ae1de..691ff7bceb7 100644 --- a/libraries/ortbConverter/README.md +++ b/libraries/ortbConverter/README.md @@ -378,7 +378,7 @@ For ease of use, the conversion logic gives special meaning to some context prop ## Prebid Server extensions -If your endpoint is a Prebid Server instance, you may take advantage of the `pbsExtension` companion library, which adds a number of processors that can populate and parse PBS-specific extensions (typically prefixed `ext.prebid`); these include bidder params (with `transformBidParams`), bidder aliases, targeting keys, and others. +If your endpoint is a Prebid Server instance, you may take advantage of the `pbsExtension` companion library, which adds a number of processors that can populate and parse PBS-specific extensions (typically prefixed `ext.prebid`); these include bidder params, bidder aliases, targeting keys, and others. ```javascript import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js' diff --git a/libraries/ortbConverter/converter.ts b/libraries/ortbConverter/converter.ts index 1f848363879..54e35ad5419 100644 --- a/libraries/ortbConverter/converter.ts +++ b/libraries/ortbConverter/converter.ts @@ -1,16 +1,16 @@ -import {compose} from './lib/composer.js'; -import {logError, memoize} from '../../src/utils.js'; -import {DEFAULT_PROCESSORS} from './processors/default.js'; -import {BID_RESPONSE, DEFAULT, getProcessors, IMP, REQUEST, RESPONSE} from '../../src/pbjsORTB.js'; -import {mergeProcessors} from './lib/mergeProcessors.js'; -import type {MediaType} from "../../src/mediaTypes.ts"; -import type {NativeRequest} from '../../src/types/ortb/native.d.ts'; -import type {ORTBImp, ORTBRequest} from "../../src/types/ortb/request.d.ts"; -import type {Currency, BidderCode} from "../../src/types/common.d.ts"; -import type {BidderRequest, BidRequest} from "../../src/adapterManager.ts"; -import type {BidResponse} from "../../src/bidfactory.ts"; -import type {AdapterResponse} from "../../src/adapters/bidderFactory.ts"; -import type {ORTBResponse} from "../../src/types/ortb/response"; +import { compose } from './lib/composer.js'; +import { logError, memoize } from '../../src/utils.js'; +import { DEFAULT_PROCESSORS } from './processors/default.js'; +import { BID_RESPONSE, DEFAULT, getProcessors, IMP, REQUEST, RESPONSE } from '../../src/pbjsORTB.js'; +import { mergeProcessors } from './lib/mergeProcessors.js'; +import type { MediaType } from "../../src/mediaTypes.ts"; +import type { NativeRequest } from '../../src/types/ortb/native.d.ts'; +import type { ORTBImp, ORTBRequest } from "../../src/types/ortb/request.d.ts"; +import type { Currency, BidderCode } from "../../src/types/common.d.ts"; +import type { BidderRequest, BidRequest } from "../../src/adapterManager.ts"; +import type { BidResponse } from "../../src/bidfactory.ts"; +import type { AdapterResponse } from "../../src/adapters/bidderFactory.ts"; +import type { ORTBResponse } from "../../src/types/ortb/response"; type Context = { [key: string]: unknown; @@ -147,18 +147,18 @@ export function ortbConverter({ return imp; }, function (error, bidRequest, context) { - logError('Error while converting bidRequest to ORTB imp; request skipped.', {error, bidRequest, context}); + logError('Error while converting bidRequest to ORTB imp; request skipped.', { error, bidRequest, context }); } ); const buildRequest = builder(REQUEST, request, function (process, imps, bidderRequest, context) { - const ortbRequest = {imp: imps}; + const ortbRequest = { imp: imps }; process(ortbRequest, bidderRequest, context); return ortbRequest; }, function (error, imps, bidderRequest, context) { - logError('Error while converting to ORTB request', {error, imps, bidderRequest, context}); + logError('Error while converting to ORTB request', { error, imps, bidderRequest, context }); throw error; } ); @@ -170,40 +170,40 @@ export function ortbConverter({ return bidResponse; }, function (error, bid, context) { - logError('Error while converting ORTB seatbid.bid to bidResponse; bid skipped.', {error, bid, context}); + logError('Error while converting ORTB seatbid.bid to bidResponse; bid skipped.', { error, bid, context }); } ); const buildResponse = builder(RESPONSE, response, function (process, bidResponses, ortbResponse, context) { - const response = {bids: bidResponses}; + const response = { bids: bidResponses }; process(response, ortbResponse, context); return response; }, function (error, bidResponses, ortbResponse, context) { - logError('Error while converting from ORTB response', {error, bidResponses, ortbResponse, context}); + logError('Error while converting from ORTB response', { error, bidResponses, ortbResponse, context }); throw error; } ); return { - toORTB({bidderRequest, bidRequests, context = {}}: { + toORTB({ bidderRequest, bidRequests, context = {} }: { bidderRequest: BidderRequest, bidRequests?: BidRequest[], context?: Context }): ORTBRequest { bidRequests = bidRequests || bidderRequest.bids; const ctx = { - req: Object.assign({bidRequests}, defaultContext, context), + req: Object.assign({ bidRequests }, defaultContext, context), imp: {} } ctx.req.impContext = ctx.imp; const imps = bidRequests.map(bidRequest => { - const impContext = Object.assign({bidderRequest, reqContext: ctx.req}, defaultContext, context); + const impContext = Object.assign({ bidderRequest, reqContext: ctx.req }, defaultContext, context); const result = buildImp(bidRequest, impContext); if (result != null) { if (result.hasOwnProperty('id')) { - Object.assign(impContext, {bidRequest, imp: result}); + Object.assign(impContext, { bidRequest, imp: result }); ctx.imp[result.id] = impContext; return result; } @@ -219,7 +219,7 @@ export function ortbConverter({ } return request; }, - fromORTB({request, response}: { + fromORTB({ request, response }: { request: ORTBRequest; response: ORTBResponse | null; }): AdapterResponse { @@ -228,13 +228,13 @@ export function ortbConverter({ throw new Error('ortbRequest passed to `fromORTB` must be the same object returned by `toORTB`') } function augmentContext(ctx, extraParams = {}) { - return Object.assign(ctx, {ortbRequest: request}, extraParams); + return Object.assign(ctx, { ortbRequest: request }, extraParams); } const impsById = Object.fromEntries((request.imp || []).map(imp => [imp.id, imp])); const bidResponses = (response?.seatbid || []).flatMap(seatbid => (seatbid.bid || []).map((bid) => { if (impsById.hasOwnProperty(bid.impid) && ctx.imp.hasOwnProperty(bid.impid)) { - return buildBidResponse(bid, augmentContext(ctx.imp[bid.impid], {imp: impsById[bid.impid], seatbid, ortbResponse: response})); + return buildBidResponse(bid, augmentContext(ctx.imp[bid.impid], { imp: impsById[bid.impid], seatbid, ortbResponse: response })); } logError('ORTB response seatbid[].bid[].impid does not match any imp in request; ignoring bid', bid); return undefined; diff --git a/libraries/ortbConverter/lib/mergeProcessors.js b/libraries/ortbConverter/lib/mergeProcessors.js index 357cecd45aa..60892c36897 100644 --- a/libraries/ortbConverter/lib/mergeProcessors.js +++ b/libraries/ortbConverter/lib/mergeProcessors.js @@ -1,4 +1,4 @@ -import {PROCESSOR_TYPES} from '../../../src/pbjsORTB.js'; +import { PROCESSOR_TYPES } from '../../../src/pbjsORTB.js'; export function mergeProcessors(...processors) { const left = processors.shift(); diff --git a/libraries/ortbConverter/processors/banner.js b/libraries/ortbConverter/processors/banner.js index 516016caa0a..007cbdbdf64 100644 --- a/libraries/ortbConverter/processors/banner.js +++ b/libraries/ortbConverter/processors/banner.js @@ -6,7 +6,7 @@ import { sizeTupleToRtbSize, encodeMacroURI } from '../../../src/utils.js'; -import {BANNER} from '../../../src/mediaTypes.js'; +import { BANNER } from '../../../src/mediaTypes.js'; /** * fill in a request `imp` with banner parameters from `bidRequest`. @@ -30,7 +30,7 @@ export function fillBannerImp(imp, bidRequest, context) { } } -export function bannerResponseProcessor({createPixel = (url) => createTrackPixelHtml(decodeURIComponent(url), encodeMacroURI)} = {}) { +export function bannerResponseProcessor({ createPixel = (url) => createTrackPixelHtml(decodeURIComponent(url), encodeMacroURI) } = {}) { return function fillBannerResponse(bidResponse, bid) { if (bidResponse.mediaType === BANNER) { if (bid.adm && bid.nurl) { diff --git a/libraries/ortbConverter/processors/default.js b/libraries/ortbConverter/processors/default.js index b1fb5be77a5..3b6b1156063 100644 --- a/libraries/ortbConverter/processors/default.js +++ b/libraries/ortbConverter/processors/default.js @@ -1,10 +1,10 @@ -import {generateUUID, mergeDeep} from '../../../src/utils.js'; -import {bannerResponseProcessor, fillBannerImp} from './banner.js'; -import {fillVideoImp, fillVideoResponse} from './video.js'; -import {setResponseMediaType} from './mediaType.js'; -import {fillNativeImp, fillNativeResponse} from './native.js'; -import {BID_RESPONSE, IMP, REQUEST} from '../../../src/pbjsORTB.js'; -import {clientSectionChecker} from '../../../src/fpd/oneClient.js'; +import { generateUUID, mergeDeep } from '../../../src/utils.js'; +import { bannerResponseProcessor, fillBannerImp } from './banner.js'; +import { fillVideoImp, fillVideoResponse } from './video.js'; +import { setResponseMediaType } from './mediaType.js'; +import { fillNativeImp, fillNativeResponse } from './native.js'; +import { BID_RESPONSE, IMP, REQUEST } from '../../../src/pbjsORTB.js'; +import { clientSectionChecker } from '../../../src/fpd/oneClient.js'; import { fillAudioImp, fillAudioResponse } from './audio.js'; export const DEFAULT_PROCESSORS = { @@ -111,6 +111,9 @@ export const DEFAULT_PROCESSORS = { if (bid.ext?.eventtrackers) { bidResponse.eventtrackers = (bidResponse.eventtrackers ?? []).concat(bid.ext.eventtrackers); } + if (bid.cattax) { + bidResponse.meta.cattax = bid.cattax; + } } } } diff --git a/libraries/ortbConverter/processors/mediaType.js b/libraries/ortbConverter/processors/mediaType.js index 67232b3ca44..4d1aed6cac9 100644 --- a/libraries/ortbConverter/processors/mediaType.js +++ b/libraries/ortbConverter/processors/mediaType.js @@ -1,4 +1,4 @@ -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; export const ORTB_MTYPES = { 1: BANNER, diff --git a/libraries/ortbConverter/processors/native.js b/libraries/ortbConverter/processors/native.js index ff231ce2b55..158bffca5fc 100644 --- a/libraries/ortbConverter/processors/native.js +++ b/libraries/ortbConverter/processors/native.js @@ -1,5 +1,5 @@ -import {isPlainObject, logWarn, mergeDeep} from '../../../src/utils.js'; -import {NATIVE} from '../../../src/mediaTypes.js'; +import { isPlainObject, logWarn, mergeDeep } from '../../../src/utils.js'; +import { NATIVE } from '../../../src/mediaTypes.js'; export function fillNativeImp(imp, bidRequest, context) { if (context.mediaType && context.mediaType !== NATIVE) return; diff --git a/libraries/ortbConverter/processors/video.js b/libraries/ortbConverter/processors/video.js index 3bb4e69e24d..dc7566ecb98 100644 --- a/libraries/ortbConverter/processors/video.js +++ b/libraries/ortbConverter/processors/video.js @@ -1,7 +1,7 @@ -import {isEmpty, logWarn, mergeDeep, sizesToSizeTuples, sizeTupleToRtbSize} from '../../../src/utils.js'; -import {VIDEO} from '../../../src/mediaTypes.js'; +import { isEmpty, logWarn, mergeDeep, sizesToSizeTuples, sizeTupleToRtbSize } from '../../../src/utils.js'; +import { VIDEO } from '../../../src/mediaTypes.js'; -import {ORTB_VIDEO_PARAMS} from '../../../src/video.js'; +import { ORTB_VIDEO_PARAMS } from '../../../src/video.js'; export function fillVideoImp(imp, bidRequest, context) { if (context.mediaType && context.mediaType !== VIDEO) return; diff --git a/libraries/pbsExtensions/pbsExtensions.js b/libraries/pbsExtensions/pbsExtensions.js index 1efded6173f..d66e8efb1e3 100644 --- a/libraries/pbsExtensions/pbsExtensions.js +++ b/libraries/pbsExtensions/pbsExtensions.js @@ -1,8 +1,8 @@ -import {mergeProcessors} from '../ortbConverter/lib/mergeProcessors.js'; -import {PBS_PROCESSORS} from './processors/pbs.js'; -import {getProcessors, PBS} from '../../src/pbjsORTB.js'; -import {defaultProcessors} from '../ortbConverter/converter.js'; -import {memoize} from '../../src/utils.js'; +import { mergeProcessors } from '../ortbConverter/lib/mergeProcessors.js'; +import { PBS_PROCESSORS } from './processors/pbs.js'; +import { getProcessors, PBS } from '../../src/pbjsORTB.js'; +import { defaultProcessors } from '../ortbConverter/converter.js'; +import { memoize } from '../../src/utils.js'; /** * ORTB converter processor set that understands Prebid Server extensions. diff --git a/libraries/pbsExtensions/processors/adUnitCode.js b/libraries/pbsExtensions/processors/adUnitCode.js index f936e0f662f..529c01aeb38 100644 --- a/libraries/pbsExtensions/processors/adUnitCode.js +++ b/libraries/pbsExtensions/processors/adUnitCode.js @@ -1,4 +1,4 @@ -import {deepSetValue} from '../../../src/utils.js'; +import { deepSetValue } from '../../../src/utils.js'; export function setImpAdUnitCode(imp, bidRequest) { const adUnitCode = bidRequest.adUnitCode; diff --git a/libraries/pbsExtensions/processors/aliases.js b/libraries/pbsExtensions/processors/aliases.js index 42dea969e6b..6a10400533c 100644 --- a/libraries/pbsExtensions/processors/aliases.js +++ b/libraries/pbsExtensions/processors/aliases.js @@ -1,8 +1,8 @@ import adapterManager from '../../../src/adapterManager.js'; -import {config} from '../../../src/config.js'; -import {deepSetValue} from '../../../src/utils.js'; +import { config } from '../../../src/config.js'; +import { deepSetValue } from '../../../src/utils.js'; -export function setRequestExtPrebidAliases(ortbRequest, bidderRequest, context, {am = adapterManager} = {}) { +export function setRequestExtPrebidAliases(ortbRequest, bidderRequest, context, { am = adapterManager } = {}) { if (am.aliasRegistry[bidderRequest.bidderCode]) { const bidder = am.bidderRegistry[bidderRequest.bidderCode]; // adding alias only if alias source bidder exists and alias isn't configured to be standalone diff --git a/libraries/pbsExtensions/processors/eventTrackers.js b/libraries/pbsExtensions/processors/eventTrackers.js index 287084a3e21..fba38168b7c 100644 --- a/libraries/pbsExtensions/processors/eventTrackers.js +++ b/libraries/pbsExtensions/processors/eventTrackers.js @@ -1,4 +1,4 @@ -import {EVENT_TYPE_IMPRESSION, EVENT_TYPE_WIN, TRACKER_METHOD_IMG} from '../../../src/eventTrackers.js'; +import { EVENT_TYPE_IMPRESSION, EVENT_TYPE_WIN, TRACKER_METHOD_IMG } from '../../../src/eventTrackers.js'; export function addEventTrackers(bidResponse, bid) { bidResponse.eventtrackers = bidResponse.eventtrackers || []; @@ -6,7 +6,7 @@ export function addEventTrackers(bidResponse, bid) { [bid.burl, EVENT_TYPE_IMPRESSION], // core used to fire burl directly, but only for bids coming from PBS [bid?.ext?.prebid?.events?.win, EVENT_TYPE_WIN] ].filter(([winUrl, type]) => winUrl && bidResponse.eventtrackers.find( - ({method, event, url}) => event === type && method === TRACKER_METHOD_IMG && url === winUrl + ({ method, event, url }) => event === type && method === TRACKER_METHOD_IMG && url === winUrl ) == null) .forEach(([url, event]) => { bidResponse.eventtrackers.push({ diff --git a/libraries/pbsExtensions/processors/mediaType.js b/libraries/pbsExtensions/processors/mediaType.js index cbcf9a013b1..1045a6ced70 100644 --- a/libraries/pbsExtensions/processors/mediaType.js +++ b/libraries/pbsExtensions/processors/mediaType.js @@ -1,5 +1,5 @@ -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; -import {ORTB_MTYPES} from '../../ortbConverter/processors/mediaType.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; +import { ORTB_MTYPES } from '../../ortbConverter/processors/mediaType.js'; export const SUPPORTED_MEDIA_TYPES = { // map from pbjs mediaType to its corresponding imp property diff --git a/libraries/pbsExtensions/processors/pageViewIds.js b/libraries/pbsExtensions/processors/pageViewIds.js index c71d32b7735..22b422e3e80 100644 --- a/libraries/pbsExtensions/processors/pageViewIds.js +++ b/libraries/pbsExtensions/processors/pageViewIds.js @@ -1,4 +1,4 @@ -import {deepSetValue} from '../../../src/utils.js'; +import { deepSetValue } from '../../../src/utils.js'; export function setRequestExtPrebidPageViewIds(ortbRequest, bidderRequest) { deepSetValue( diff --git a/libraries/pbsExtensions/processors/params.js b/libraries/pbsExtensions/processors/params.js index 1dadb02fde3..949835382ff 100644 --- a/libraries/pbsExtensions/processors/params.js +++ b/libraries/pbsExtensions/processors/params.js @@ -1,4 +1,4 @@ -import {deepSetValue} from '../../../src/utils.js'; +import { deepSetValue } from '../../../src/utils.js'; export function setImpBidParams(imp, bidRequest) { const params = bidRequest.params; diff --git a/libraries/pbsExtensions/processors/pbs.js b/libraries/pbsExtensions/processors/pbs.js index 3fa97ae674b..001a4db07bc 100644 --- a/libraries/pbsExtensions/processors/pbs.js +++ b/libraries/pbsExtensions/processors/pbs.js @@ -1,13 +1,13 @@ -import {BID_RESPONSE, IMP, REQUEST, RESPONSE} from '../../../src/pbjsORTB.js'; -import {isPlainObject, isStr, mergeDeep} from '../../../src/utils.js'; -import {extPrebidMediaType} from './mediaType.js'; -import {setRequestExtPrebidAliases} from './aliases.js'; -import {setImpBidParams} from './params.js'; -import {setImpAdUnitCode} from './adUnitCode.js'; -import {setRequestExtPrebid, setRequestExtPrebidChannel} from './requestExtPrebid.js'; -import {setBidResponseVideoCache} from './video.js'; -import {addEventTrackers} from './eventTrackers.js'; -import {setRequestExtPrebidPageViewIds} from './pageViewIds.js'; +import { BID_RESPONSE, IMP, REQUEST, RESPONSE } from '../../../src/pbjsORTB.js'; +import { isPlainObject, isStr, mergeDeep } from '../../../src/utils.js'; +import { extPrebidMediaType } from './mediaType.js'; +import { setRequestExtPrebidAliases } from './aliases.js'; +import { setImpBidParams } from './params.js'; +import { setImpAdUnitCode } from './adUnitCode.js'; +import { setRequestExtPrebid, setRequestExtPrebidChannel } from './requestExtPrebid.js'; +import { setBidResponseVideoCache } from './video.js'; +import { addEventTrackers } from './eventTrackers.js'; +import { setRequestExtPrebidPageViewIds } from './pageViewIds.js'; export const PBS_PROCESSORS = { [REQUEST]: { @@ -30,7 +30,7 @@ export const PBS_PROCESSORS = { }, [IMP]: { params: { - // sets bid ext.prebid.bidder.[bidderCode] with bidRequest.params, passed through transformBidParams if necessary + // sets bid ext.prebid.bidder.[bidderCode] with bidRequest.params fn: setImpBidParams }, adUnitCode: { diff --git a/libraries/pbsExtensions/processors/requestExtPrebid.js b/libraries/pbsExtensions/processors/requestExtPrebid.js index bbb6add45ce..780a2d08883 100644 --- a/libraries/pbsExtensions/processors/requestExtPrebid.js +++ b/libraries/pbsExtensions/processors/requestExtPrebid.js @@ -1,6 +1,6 @@ -import {deepSetValue, mergeDeep} from '../../../src/utils.js'; -import {config} from '../../../src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { deepSetValue, mergeDeep } from '../../../src/utils.js'; +import { config } from '../../../src/config.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export function setRequestExtPrebid(ortbRequest, bidderRequest) { deepSetValue( diff --git a/libraries/pbsExtensions/processors/video.js b/libraries/pbsExtensions/processors/video.js index bcc24eea1b1..235c1ac3947 100644 --- a/libraries/pbsExtensions/processors/video.js +++ b/libraries/pbsExtensions/processors/video.js @@ -1,12 +1,12 @@ -import {VIDEO} from '../../../src/mediaTypes.js'; +import { VIDEO } from '../../../src/mediaTypes.js'; export function setBidResponseVideoCache(bidResponse, bid) { if (bidResponse.mediaType === VIDEO) { // try to get cache values from 'response.ext.prebid.cache' // else try 'bid.ext.prebid.targeting' as fallback - let {cacheId: videoCacheKey, url: vastUrl} = bid?.ext?.prebid?.cache?.vastXml ?? {}; + let { cacheId: videoCacheKey, url: vastUrl } = bid?.ext?.prebid?.cache?.vastXml ?? {}; if (!videoCacheKey || !vastUrl) { - const {hb_uuid: uuid, hb_cache_host: cacheHost, hb_cache_path: cachePath} = bid?.ext?.prebid?.targeting ?? {}; + const { hb_uuid: uuid, hb_cache_host: cacheHost, hb_cache_path: cachePath } = bid?.ext?.prebid?.targeting ?? {}; if (uuid && cacheHost && cachePath) { videoCacheKey = uuid; vastUrl = `https://${cacheHost}${cachePath}?uuid=${uuid}`; diff --git a/libraries/percentInView/percentInView.js b/libraries/percentInView/percentInView.js index 27148e40941..0de3a9c257d 100644 --- a/libraries/percentInView/percentInView.js +++ b/libraries/percentInView/percentInView.js @@ -1,8 +1,31 @@ import { getWinDimensions, inIframe } from '../../src/utils.js'; import { getBoundingClientRect } from '../boundingClientRect/boundingClientRect.js'; -export function getBoundingBox(element, {w, h} = {}) { - let {width, height, left, top, right, bottom, x, y} = getBoundingClientRect(element); +/** + * return the offset between the given window's viewport and the top window's. + */ +export function getViewportOffset(win = window) { + let x = 0; + let y = 0; + try { + while (win?.frameElement != null) { + const rect = getBoundingClientRect(win.frameElement); + x += rect.left; + y += rect.top; + win = win.parent; + } + } catch (e) { + // offset cannot be calculated as some parents are cross-frame + // fallback to 0,0 + x = 0; + y = 0; + } + + return { x, y }; +} + +export function getBoundingBox(element, { w, h } = {}) { + let { width, height, left, top, right, bottom, x, y } = getBoundingClientRect(element); if ((width === 0 || height === 0) && w && h) { width = w; @@ -11,7 +34,7 @@ export function getBoundingBox(element, {w, h} = {}) { bottom = top + h; } - return {width, height, left, top, right, bottom, x, y}; + return { width, height, left, top, right, bottom, x, y }; } function getIntersectionOfRects(rects) { @@ -41,17 +64,27 @@ function getIntersectionOfRects(rects) { return bbox; } -export const percentInView = (element, {w, h} = {}) => { - const elementBoundingBox = getBoundingBox(element, {w, h}); +export const percentInView = (element, { w, h } = {}) => { + const elementBoundingBox = getBoundingBox(element, { w, h }); + + // when in an iframe, the bounding box is relative to the iframe's viewport + // since we are intersecting it with the top window's viewport, attempt to + // compensate for the offset between them + + const offset = getViewportOffset(element?.ownerDocument?.defaultView); + elementBoundingBox.left += offset.x; + elementBoundingBox.right += offset.x; + elementBoundingBox.top += offset.y; + elementBoundingBox.bottom += offset.y; - const { innerHeight, innerWidth } = getWinDimensions(); + const dims = getWinDimensions(); // Obtain the intersection of the element and the viewport const elementInViewBoundingBox = getIntersectionOfRects([{ left: 0, top: 0, - right: innerWidth, - bottom: innerHeight + right: dims.document.documentElement.clientWidth, + bottom: dims.document.documentElement.clientHeight }, elementBoundingBox]); let elementInViewArea, elementTotalArea; diff --git a/libraries/placementPositionInfo/placementPositionInfo.js b/libraries/placementPositionInfo/placementPositionInfo.js new file mode 100644 index 00000000000..884f8e7c5f8 --- /dev/null +++ b/libraries/placementPositionInfo/placementPositionInfo.js @@ -0,0 +1,87 @@ +import { getBoundingClientRect } from '../boundingClientRect/boundingClientRect.js'; +import { canAccessWindowTop, cleanObj, getWinDimensions, getWindowSelf, getWindowTop } from '../../src/utils.js'; +import { getViewability, getViewportOffset } from '../percentInView/percentInView.js'; + +export function getPlacementPositionUtils() { + const topWin = canAccessWindowTop() ? getWindowTop() : getWindowSelf(); + const selfWin = getWindowSelf(); + + const getViewportHeight = () => { + const dim = getWinDimensions(); + return dim.innerHeight || dim.document.documentElement.clientHeight || dim.document.body.clientHeight || 0; + }; + + const getPageHeight = () => { + const dim = getWinDimensions(); + const body = dim.document.body; + const html = dim.document.documentElement; + if (!body || !html) return 0; + + return Math.max( + body.scrollHeight, + body.offsetHeight, + html.clientHeight, + html.scrollHeight, + html.offsetHeight + ); + }; + + const getViewableDistance = (element, frameOffset) => { + if (!element) return { distanceToView: 0, elementHeight: 0 }; + + const elementRect = getBoundingClientRect(element); + if (!elementRect) return { distanceToView: 0, elementHeight: 0 }; + + const elementTop = elementRect.top + frameOffset.y; + const elementBottom = elementRect.bottom + frameOffset.y; + const viewportHeight = getViewportHeight(); + + let distanceToView; + if (elementTop - viewportHeight <= 0 && elementBottom >= 0) { + distanceToView = 0; + } else if (elementTop - viewportHeight > 0) { + distanceToView = Math.round(elementTop - viewportHeight); + } else { + distanceToView = Math.round(elementBottom); + } + + return { distanceToView, elementHeight: elementRect.height }; + }; + + function getPlacementInfo(bidReq) { + const element = selfWin.document.getElementById(bidReq.adUnitCode); + const frameOffset = getViewportOffset(); + const { distanceToView, elementHeight } = getViewableDistance(element, frameOffset); + + const sizes = (bidReq.sizes || []).map(size => ({ + w: Number.parseInt(size[0], 10), + h: Number.parseInt(size[1], 10) + })); + const size = sizes.length > 0 + ? sizes.reduce((min, size) => size.h * size.w < min.h * min.w ? size : min, sizes[0]) + : {}; + + const placementPercentView = element ? getViewability(element, topWin, size) : 0; + + return cleanObj({ + AuctionsCount: bidReq.auctionsCount, + DistanceToView: distanceToView, + PlacementPercentView: Math.round(placementPercentView), + ElementHeight: Math.round(elementHeight) || 1 + }); + } + + function getPlacementEnv() { + return cleanObj({ + TimeFromNavigation: Math.floor(performance.now()), + TabActive: topWin.document.visibilityState === 'visible', + PageHeight: getPageHeight(), + ViewportHeight: getViewportHeight() + }); + } + + return { + getPlacementInfo, + getPlacementEnv + }; +} diff --git a/libraries/riseUtils/constants.js b/libraries/riseUtils/constants.js index 7c2e4b52f8c..0ed9691db6e 100644 --- a/libraries/riseUtils/constants.js +++ b/libraries/riseUtils/constants.js @@ -1,4 +1,4 @@ -import {BANNER, NATIVE, VIDEO} from '../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../src/mediaTypes.js'; const OW_GVLID = 280 export const SUPPORTED_AD_TYPES = [BANNER, VIDEO, NATIVE]; diff --git a/libraries/riseUtils/index.js b/libraries/riseUtils/index.js index 77ca87f0fca..5805f2c8264 100644 --- a/libraries/riseUtils/index.js +++ b/libraries/riseUtils/index.js @@ -10,12 +10,12 @@ import { logInfo, triggerPixel } from '../../src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../../src/mediaTypes.js'; -import {config} from '../../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../../src/mediaTypes.js'; +import { config } from '../../src/config.js'; import { getDNT } from '../dnt/index.js'; -import {ADAPTER_VERSION, DEFAULT_CURRENCY, DEFAULT_TTL, SUPPORTED_AD_TYPES} from './constants.js'; +import { ADAPTER_VERSION, DEFAULT_CURRENCY, DEFAULT_TTL, SUPPORTED_AD_TYPES } from './constants.js'; -import {getGlobalVarName} from '../../src/buildOptions.js'; +import { getGlobalVarName } from '../../src/buildOptions.js'; export const makeBaseSpec = (baseUrl, modes) => { return { @@ -350,7 +350,7 @@ export function buildBidResponse(adUnit) { } else if (adUnit.mediaType === BANNER) { bidResponse.ad = adUnit.ad; } else if (adUnit.mediaType === NATIVE) { - bidResponse.native = {ortb: adUnit.native}; + bidResponse.native = { ortb: adUnit.native }; } if (adUnit.adomain && adUnit.adomain.length) { diff --git a/libraries/storageDisclosure/summary.mjs b/libraries/storageDisclosure/summary.mjs index 3946efaddd8..7953fd06a12 100644 --- a/libraries/storageDisclosure/summary.mjs +++ b/libraries/storageDisclosure/summary.mjs @@ -6,9 +6,9 @@ export function getStorageDisclosureSummary(moduleNames, getModuleMetadata) { moduleNames.forEach(moduleName => { const disclosure = getModuleMetadata(moduleName)?.disclosures; if (!disclosure) return; - Object.entries(disclosure).forEach(([url, {disclosures: identifiers}]) => { + Object.entries(disclosure).forEach(([url, { disclosures: identifiers }]) => { if (summary.hasOwnProperty(url)) { - summary[url].forEach(({disclosedBy}) => disclosedBy.push(moduleName)); + summary[url].forEach(({ disclosedBy }) => disclosedBy.push(moduleName)); } else if (identifiers?.length > 0) { summary[url] = identifiers.map(identifier => ({ disclosedIn: url, diff --git a/libraries/targetVideoUtils/bidderUtils.js b/libraries/targetVideoUtils/bidderUtils.js index b082cfbe5cf..a30e572d83a 100644 --- a/libraries/targetVideoUtils/bidderUtils.js +++ b/libraries/targetVideoUtils/bidderUtils.js @@ -1,7 +1,7 @@ -import {SYNC_URL} from './constants.js'; -import {VIDEO} from '../../src/mediaTypes.js'; -import {getRefererInfo} from '../../src/refererDetection.js'; -import {createTrackPixelHtml, getBidRequest, formatQS} from '../../src/utils.js'; +import { SYNC_URL } from './constants.js'; +import { VIDEO } from '../../src/mediaTypes.js'; +import { getRefererInfo } from '../../src/refererDetection.js'; +import { createTrackPixelHtml, getBidRequest, formatQS } from '../../src/utils.js'; export function getSizes(request) { let sizes = request.sizes; @@ -18,7 +18,7 @@ export function getSizes(request) { return sizes; } -export function formatRequest({payload, url, bidderRequest, bidId}) { +export function formatRequest({ payload, url, bidderRequest, bidId }) { const request = { method: 'POST', data: JSON.stringify(payload), @@ -94,7 +94,7 @@ export function bannerBid(serverBid, rtbBid, bidderRequest, margin) { } export function videoBid(serverBid, requestId, currency, params, ttl) { - const {ad, adUrl, vastUrl, vastXml} = getAd(serverBid); + const { ad, adUrl, vastUrl, vastXml } = getAd(serverBid); const bid = { requestId, @@ -165,7 +165,7 @@ export function getAd(bid) { }; } - return {ad, adUrl, vastXml, vastUrl}; + return { ad, adUrl, vastXml, vastUrl }; } export function getSyncResponse(syncOptions, gdprConsent, uspConsent, gppConsent, endpoint) { diff --git a/libraries/teqblazeUtils/bidderUtils.js b/libraries/teqblazeUtils/bidderUtils.js index f310f2304d2..f57cb30ffa7 100644 --- a/libraries/teqblazeUtils/bidderUtils.js +++ b/libraries/teqblazeUtils/bidderUtils.js @@ -200,7 +200,7 @@ export const buildRequests = (adUrl) => (validBidRequests = [], bidderRequest = return buildRequestsBase({ adUrl, validBidRequests, bidderRequest, placementProcessingFunction }); }; -export function interpretResponseBuilder({addtlBidValidation = (bid) => true} = {}) { +export function interpretResponseBuilder({ addtlBidValidation = (bid) => true } = {}) { return function (serverResponse) { const response = []; for (let i = 0; i < serverResponse.body.length; i++) { @@ -231,8 +231,8 @@ export const getUserSyncs = (syncUrl) => (syncOptions, serverResponses, gdprCons } } - if (uspConsent && uspConsent.consentString) { - url += `&ccpa_consent=${uspConsent.consentString}`; + if (uspConsent) { + url += `&ccpa_consent=${uspConsent}`; } if (gppConsent?.gppString && gppConsent?.applicableSections?.length) { diff --git a/libraries/timezone/timezone.js b/libraries/timezone/timezone.js index e4ef39f28ef..87d00bee43c 100644 --- a/libraries/timezone/timezone.js +++ b/libraries/timezone/timezone.js @@ -1,3 +1,8 @@ +import { isFingerprintingApiDisabled } from '../fingerprinting/fingerprinting.js'; + export function getTimeZone() { + if (isFingerprintingApiDisabled('resolvedoptions')) { + return ''; + } return Intl.DateTimeFormat().resolvedOptions().timeZone; } diff --git a/libraries/transformParamsUtils/convertTypes.js b/libraries/transformParamsUtils/convertTypes.js index 813d8e6e693..59611d52817 100644 --- a/libraries/transformParamsUtils/convertTypes.js +++ b/libraries/transformParamsUtils/convertTypes.js @@ -1,4 +1,4 @@ -import {isFn} from '../../src/utils.js'; +import { isFn } from '../../src/utils.js'; /** * Try to convert a value to a type. diff --git a/libraries/uid1Eids/uid1Eids.js b/libraries/uid1Eids/uid1Eids.js index 5bf3dde5c6c..4b45c984058 100644 --- a/libraries/uid1Eids/uid1Eids.js +++ b/libraries/uid1Eids/uid1Eids.js @@ -10,7 +10,7 @@ export const UID1_EIDS = { } }, getUidExt: function(data) { - return {...{rtiPartner: 'TDID'}, ...data.ext} + return { ...{ rtiPartner: 'TDID' }, ...data.ext } } } } diff --git a/libraries/uid2IdSystemShared/uid2IdSystem_shared.js b/libraries/uid2IdSystemShared/uid2IdSystem_shared.js index 70a607a0f8f..aa9af0844d7 100644 --- a/libraries/uid2IdSystemShared/uid2IdSystem_shared.js +++ b/libraries/uid2IdSystemShared/uid2IdSystem_shared.js @@ -33,14 +33,17 @@ export class Uid2ApiClient { } return arrayBuffer; } + hasStatusResponse(response) { return typeof (response) === 'object' && response && response.status; } + isValidRefreshResponse(response) { return this.hasStatusResponse(response) && ( response.status === 'optout' || response.status === 'expired_token' || (response.status === 'success' && response.body && isValidIdentity(response.body)) ); } + ResponseToRefreshResult(response) { if (this.isValidRefreshResponse(response)) { if (response.status === 'success') { return { status: response.status, identity: response.body }; } @@ -48,6 +51,7 @@ export class Uid2ApiClient { return response; } else { return prependMessage(`Response didn't contain a valid status`); } } + callRefreshApi(refreshDetails) { const url = this._baseUrl + '/v2/token/refresh'; let resolvePromise; @@ -98,10 +102,12 @@ export class Uid2ApiClient { rejectPromise(prependMessage(error)); } } - }, refreshDetails.refresh_token, { method: 'POST', + }, refreshDetails.refresh_token, { + method: 'POST', customHeaders: { 'X-UID2-Client-Version': this._clientVersion - } }); + } + }); return promise; } } @@ -112,30 +118,39 @@ export class Uid2StorageManager { this._storageName = storageName; this._logInfo = (...args) => logInfoWrapper(logInfo, ...args); } + readCookie(cookieName) { return this._storage.cookiesAreEnabled() ? this._storage.getCookie(cookieName) : null; } + readLocalStorage(key) { return this._storage.localStorageIsEnabled() ? this._storage.getDataFromLocalStorage(key) : null; } + readModuleCookie() { return this.parseIfContainsBraces(this.readCookie(this._storageName)); } + writeModuleCookie(value) { this._storage.setCookie(this._storageName, JSON.stringify(value), Date.now() + 60 * 60 * 24 * 1000); } + readModuleStorage() { return this.parseIfContainsBraces(this.readLocalStorage(this._storageName)); } + writeModuleStorage(value) { this._storage.setDataInLocalStorage(this._storageName, JSON.stringify(value)); } + readProvidedCookie(cookieName) { return JSON.parse(this.readCookie(cookieName)); } + parseIfContainsBraces(value) { return (value?.includes('{')) ? JSON.parse(value) : value; } + storeValue(value) { if (this._preferLocalStorage) { this.writeModuleStorage(value); @@ -176,7 +191,7 @@ export class Uid2StorageManager { function refreshTokenAndStore(baseUrl, token, clientId, storageManager, _logInfo, _logWarn) { _logInfo('UID2 base url provided: ', baseUrl); - const client = new Uid2ApiClient({baseUrl}, clientId, _logInfo, _logWarn); + const client = new Uid2ApiClient({ baseUrl }, clientId, _logInfo, _logWarn); return client.callRefreshApi(token).then((response) => { _logInfo('Refresh endpoint responded with:', response); const tokens = { @@ -744,12 +759,14 @@ export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) { if (!storedTokens || Date.now() > storedTokens.latestToken.refresh_expires) { const promise = clientSideTokenGenerator.generateTokenAndStore(config.apiBaseUrl, config.cstg, cstgIdentity, storageManager, logInfo, _logWarn); logInfo('Generate token using CSTG'); - return { callback: (cb) => { - promise.then((result) => { - logInfo('Token generation responded, passing the new token on.', result); - cb(result); - }).catch((e) => { logError('error generating token: ', e); }); - } }; + return { + callback: (cb) => { + promise.then((result) => { + logInfo('Token generation responded, passing the new token on.', result); + cb(result); + }).catch((e) => { logError('error generating token: ', e); }); + } + }; } } } @@ -764,12 +781,14 @@ export function Uid2GetId(config, prebidStorageManager, _logInfo, _logWarn) { if (Date.now() > newestAvailableToken.identity_expires) { const promise = refreshTokenAndStore(config.apiBaseUrl, newestAvailableToken, config.clientId, storageManager, logInfo, _logWarn); logInfo('Token is expired but can be refreshed, attempting refresh.'); - return { callback: (cb) => { - promise.then((result) => { - logInfo('Refresh reponded, passing the updated token on.', result); - cb(result); - }).catch((e) => { logError('error refreshing token: ', e); }); - } }; + return { + callback: (cb) => { + promise.then((result) => { + logInfo('Refresh reponded, passing the updated token on.', result); + cb(result); + }).catch((e) => { logError('error refreshing token: ', e); }); + } + }; } const tokens = { originalToken: suppliedToken ?? storedTokens?.originalToken, diff --git a/libraries/utiqUtils/utiqUtils.ts b/libraries/utiqUtils/utiqUtils.ts index 347c5a973d2..dd2ea9ff06c 100644 --- a/libraries/utiqUtils/utiqUtils.ts +++ b/libraries/utiqUtils/utiqUtils.ts @@ -30,7 +30,7 @@ export function findUtiqService(storage: any, refreshUserIds: () => void, logPre logInfo(`${logPrefix}: frame found: `, Boolean(utiqFrame)); if (utiqFrame) { window.addEventListener('message', (event) => { - const {action, idGraphData, description} = event.data; + const { action, idGraphData, description } = event.data; if (action === 'returnIdGraphEntry' && description.moduleName === moduleName) { // Use the IDs received from the parent website if (event.origin !== window.origin) { diff --git a/libraries/vastTrackers/vastTrackers.js b/libraries/vastTrackers/vastTrackers.js index 7ab1650e9f9..0936ab02609 100644 --- a/libraries/vastTrackers/vastTrackers.js +++ b/libraries/vastTrackers/vastTrackers.js @@ -1,10 +1,10 @@ -import {callPrebidCache} from '../../src/auction.js'; -import {VIDEO} from '../../src/mediaTypes.js'; -import {logError} from '../../src/utils.js'; -import {isActivityAllowed} from '../../src/activities/rules.js'; -import {ACTIVITY_REPORT_ANALYTICS} from '../../src/activities/activities.js'; -import {activityParams} from '../../src/activities/activityParams.js'; -import {auctionManager} from '../../src/auctionManager.js'; +import { callPrebidCache } from '../../src/auction.js'; +import { VIDEO } from '../../src/mediaTypes.js'; +import { logError } from '../../src/utils.js'; +import { isActivityAllowed } from '../../src/activities/rules.js'; +import { ACTIVITY_REPORT_ANALYTICS } from '../../src/activities/activities.js'; +import { activityParams } from '../../src/activities/activityParams.js'; +import { auctionManager } from '../../src/auctionManager.js'; const vastTrackers = []; let enabled = false; @@ -22,15 +22,15 @@ export function enable() { export function disable() { if (enabled) { - callPrebidCache.getHooks({hook: addTrackersToResponse}).remove(); + callPrebidCache.getHooks({ hook: addTrackersToResponse }).remove(); enabled = false; } } -export function cacheVideoBidHook({index = auctionManager.index} = {}) { +export function cacheVideoBidHook({ index = auctionManager.index } = {}) { return function addTrackersToResponse(next, auctionInstance, bidResponse, afterBidAdded, videoMediaType) { if (FEATURES.VIDEO && bidResponse.mediaType === VIDEO) { - const vastTrackers = getVastTrackers(bidResponse, {index}); + const vastTrackers = getVastTrackers(bidResponse, { index }); if (vastTrackers) { bidResponse.vastXml = insertVastTrackers(vastTrackers, bidResponse.vastXml); const impTrackers = vastTrackers.get('impressions'); @@ -48,7 +48,7 @@ enable(); export function registerVastTrackers(moduleType, moduleName, trackerFn) { if (typeof trackerFn === 'function') { - vastTrackers.push({'moduleType': moduleType, 'moduleName': moduleName, 'trackerFn': trackerFn}); + vastTrackers.push({ 'moduleType': moduleType, 'moduleName': moduleName, 'trackerFn': trackerFn }); } } @@ -74,7 +74,7 @@ export function insertVastTrackers(trackers, vastXml) { return vastXml; } -export function getVastTrackers(bid, {index = auctionManager.index}) { +export function getVastTrackers(bid, { index = auctionManager.index }) { const trackers = []; vastTrackers.filter( ({ @@ -82,10 +82,10 @@ export function getVastTrackers(bid, {index = auctionManager.index}) { moduleName, trackerFn }) => isActivityAllowed(ACTIVITY_REPORT_ANALYTICS, activityParams(moduleType, moduleName)) - ).forEach(({trackerFn}) => { + ).forEach(({ trackerFn }) => { const auction = index.getAuction(bid).getProperties(); const bidRequest = index.getBidRequest(bid); - const trackersToAdd = trackerFn(bid, {auction, bidRequest}); + const trackersToAdd = trackerFn(bid, { auction, bidRequest }); trackersToAdd.forEach(trackerToAdd => { if (isValidVastTracker(trackers, trackerToAdd)) { trackers.push(trackerToAdd); @@ -101,7 +101,7 @@ function isValidVastTracker(trackers, trackerToAdd) { } function trackersToMap(trackers) { - return trackers.reduce((map, {url, event}) => { + return trackers.reduce((map, { url, event }) => { !map.has(event) && map.set(event, new Set()); map.get(event).add(url); return map; diff --git a/libraries/vidazooUtils/bidderUtils.js b/libraries/vidazooUtils/bidderUtils.js index fa2cea1b6fa..331cf5bc4b1 100644 --- a/libraries/vidazooUtils/bidderUtils.js +++ b/libraries/vidazooUtils/bidderUtils.js @@ -9,11 +9,11 @@ import { uniques, getWinDimensions } from '../../src/utils.js'; -import {chunk} from '../chunk/chunk.js'; -import {CURRENCY, DEAL_ID_EXPIRY, SESSION_ID_KEY, TTL_SECONDS, UNIQUE_DEAL_ID_EXPIRY} from './constants.js'; -import {bidderSettings} from '../../src/bidderSettings.js'; -import {config} from '../../src/config.js'; -import {BANNER, VIDEO} from '../../src/mediaTypes.js'; +import { chunk } from '../chunk/chunk.js'; +import { CURRENCY, DEAL_ID_EXPIRY, SESSION_ID_KEY, TTL_SECONDS, UNIQUE_DEAL_ID_EXPIRY } from './constants.js'; +import { bidderSettings } from '../../src/bidderSettings.js'; +import { config } from '../../src/config.js'; +import { BANNER, VIDEO } from '../../src/mediaTypes.js'; export function createSessionId() { return 'wsid_' + parseInt(Date.now() * Math.random()); @@ -21,7 +21,7 @@ export function createSessionId() { export function getTopWindowQueryParams() { try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -56,7 +56,7 @@ export function tryParseJSON(value) { export function setStorageItem(storage, key, value, timestamp) { try { const created = timestamp || Date.now(); - const data = JSON.stringify({value, created}); + const data = JSON.stringify({ value, created }); storage.setDataInLocalStorage(key, data); } catch (e) { } @@ -168,9 +168,9 @@ export function createUserSyncGetter(options = { }) { return function getUserSyncs(syncOptions, responses, gdprConsent = {}, uspConsent = '', gppConsent = {}) { const syncs = []; - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; - const {gppString, applicableSections} = gppConsent; + const { iframeEnabled, pixelEnabled } = syncOptions; + const { gdprApplies, consentString = '' } = gdprConsent; + const { gppString, applicableSections } = gppConsent; const coppa = config.getConfig('coppa') ? 1 : 0; const cidArr = responses.filter(resp => resp?.body?.cid).map(resp => resp.body.cid).filter(uniques); @@ -239,8 +239,8 @@ export function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidder bidderRequestsCount, bidderWinsCount } = bid; - const {ext} = params; - let {bidFloor} = params; + const { ext } = params; + let { bidFloor } = params; const hashUrl = hashCode(topWindowUrl); const uniqueRequestData = isFn(getUniqueRequestData) ? getUniqueRequestData(hashUrl, bid) : {}; const uniqueDealId = getUniqueDealId(storage, hashUrl); @@ -392,7 +392,7 @@ export function createInterpretResponseFn(bidderCode, allowSingleRequest) { const singleRequestMode = allowSingleRequest && config.getConfig(`${bidderCode}.singleRequest`); const reqBidId = request?.data?.bidId; - const {results} = serverResponse.body; + const { results } = serverResponse.body; const output = []; @@ -465,7 +465,7 @@ export function createInterpretResponseFn(bidderCode, allowSingleRequest) { export function createBuildRequestsFn(createRequestDomain, createUniqueRequestData, storage, bidderCode, bidderVersion, allowSingleRequest) { function buildRequest(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout) { - const {params} = bid; + const { params } = bid; const cId = extractCID(params); const subDomain = extractSubDomain(params); const data = buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidderTimeout, storage, bidderVersion, bidderCode, createUniqueRequestData); @@ -476,7 +476,7 @@ export function createBuildRequestsFn(createRequestDomain, createUniqueRequestDa } function buildSingleRequest(bidRequests, bidderRequest, topWindowUrl, bidderTimeout) { - const {params} = bidRequests[0]; + const { params } = bidRequests[0]; const cId = extractCID(params); const subDomain = extractSubDomain(params); const data = bidRequests.map(bid => { diff --git a/libraries/viewport/viewport.js b/libraries/viewport/viewport.js index 18c3818de00..77b4da35699 100644 --- a/libraries/viewport/viewport.js +++ b/libraries/viewport/viewport.js @@ -1,4 +1,4 @@ -import {getWinDimensions, getWindowTop} from '../../src/utils.js'; +import { getWinDimensions, getWindowTop } from '../../src/utils.js'; export function getViewportCoordinates() { try { diff --git a/libraries/weakStore/weakStore.js b/libraries/weakStore/weakStore.js index 09606354dae..30b862b76ec 100644 --- a/libraries/weakStore/weakStore.js +++ b/libraries/weakStore/weakStore.js @@ -1,4 +1,4 @@ -import {auctionManager} from '../../src/auctionManager.js'; +import { auctionManager } from '../../src/auctionManager.js'; export function weakStore(get) { const store = new WeakMap(); @@ -12,4 +12,4 @@ export function weakStore(get) { }; } -export const auctionStore = () => weakStore((auctionId) => auctionManager.index.getAuction({auctionId})); +export const auctionStore = () => weakStore((auctionId) => auctionManager.index.getAuction({ auctionId })); diff --git a/libraries/webdriver/webdriver.js b/libraries/webdriver/webdriver.js index 957fea62ed8..de53fb6bc8e 100644 --- a/libraries/webdriver/webdriver.js +++ b/libraries/webdriver/webdriver.js @@ -1,9 +1,49 @@ -import {canAccessWindowTop, internal as utilsInternals} from '../../src/utils.js'; +import { isFingerprintingApiDisabled } from '../fingerprinting/fingerprinting.js'; +import { getFallbackWindow } from '../../src/utils.js'; /** * Warning: accessing navigator.webdriver may impact fingerprinting scores when this API is included in the built script. + * @param {Window} [win] Window to check (defaults to top or self) + * @returns {boolean} */ -export function isWebdriverEnabled() { - const win = canAccessWindowTop() ? utilsInternals.getWindowTop() : utilsInternals.getWindowSelf(); - return win.navigator?.webdriver === true; +export function isWebdriverEnabled(win) { + if (isFingerprintingApiDisabled('webdriver')) { + return false; + } + return getFallbackWindow(win).navigator?.webdriver === true; +} + +/** + * Detects Selenium/WebDriver via document/window properties (e.g. __webdriver_script_fn, attributes). + * @param {Window} [win] Window to check + * @param {Document} [doc] Document to check (defaults to win.document) + * @returns {boolean} + */ +export function isSeleniumDetected(win, doc) { + if (isFingerprintingApiDisabled('webdriver')) { + return false; + } + const _win = win || (typeof window !== 'undefined' ? window : undefined); + const _doc = doc || (_win?.document); + if (!_win || !_doc) return false; + const checks = [ + 'webdriver' in _win, + '_Selenium_IDE_Recorder' in _win, + 'callSelenium' in _win, + '_selenium' in _win, + '__webdriver_script_fn' in _doc, + '__driver_evaluate' in _doc, + '__webdriver_evaluate' in _doc, + '__selenium_evaluate' in _doc, + '__fxdriver_evaluate' in _doc, + '__driver_unwrapped' in _doc, + '__webdriver_unwrapped' in _doc, + '__selenium_unwrapped' in _doc, + '__fxdriver_unwrapped' in _doc, + '__webdriver_script_func' in _doc, + _doc.documentElement?.getAttribute('selenium') !== null, + _doc.documentElement?.getAttribute('webdriver') !== null, + _doc.documentElement?.getAttribute('driver') !== null + ]; + return checks.some(Boolean); } diff --git a/libraries/xeUtils/bidderUtils.js b/libraries/xeUtils/bidderUtils.js index dbf9d79207d..91f5992921f 100644 --- a/libraries/xeUtils/bidderUtils.js +++ b/libraries/xeUtils/bidderUtils.js @@ -1,5 +1,5 @@ -import {deepAccess, getBidIdParameter, isFn, logError, isArray, parseSizesInput, isPlainObject} from '../../src/utils.js'; -import {getAdUnitSizes} from '../sizeUtils/sizeUtils.js'; +import { deepAccess, getBidIdParameter, isFn, logError, isArray, parseSizesInput, isPlainObject } from '../../src/utils.js'; +import { getAdUnitSizes } from '../sizeUtils/sizeUtils.js'; export function getBidFloor(bid, currency = 'USD') { if (!isFn(bid.getFloor)) { @@ -41,7 +41,7 @@ export function isBidRequestValid(bid, requiredParams = ['pid', 'env']) { } export function buildRequests(validBidRequests, bidderRequest, endpoint) { - const {refererInfo = {}, gdprConsent = {}, uspConsent} = bidderRequest; + const { refererInfo = {}, gdprConsent = {}, uspConsent } = bidderRequest; const requests = validBidRequests.map(req => { const request = {}; request.tmax = bidderRequest.timeout || 0; @@ -108,7 +108,7 @@ export function buildRequests(validBidRequests, bidderRequest, endpoint) { }; } -export function interpretResponse(serverResponse, {bidderRequest}) { +export function interpretResponse(serverResponse, { bidderRequest }) { const response = []; if (!isArray(deepAccess(serverResponse, 'body.data'))) { return response; @@ -143,7 +143,7 @@ export function getUserSyncs(syncOptions, serverResponses, gdprConsent = {}, usp pixels.forEach(pixel => { const [type, url] = pixel; - const sync = {type, url: `${url}&${usPrivacy}${gdprFlag}${gdprString}`}; + const sync = { type, url: `${url}&${usPrivacy}${gdprFlag}${gdprString}` }; if (type === 'iframe' && syncOptions.iframeEnabled) { syncs.push(sync) } else if (type === 'image' && syncOptions.pixelEnabled) { diff --git a/metadata/core.json b/metadata/core.json index 1e43a89e586..faacd3ceed4 100644 --- a/metadata/core.json +++ b/metadata/core.json @@ -11,6 +11,12 @@ "moduleName": "prebid-core", "disclosureURL": "local://prebid/probes.json" }, + { + "componentType": "prebid", + "componentName": "storage", + "moduleName": "prebid-core", + "disclosureURL": "local://prebid/probes.json" + }, { "componentType": "prebid", "componentName": "debugging", diff --git a/metadata/disclosures/prebid/probes.json b/metadata/disclosures/prebid/probes.json index c371cef1d4e..16cc5dec160 100644 --- a/metadata/disclosures/prebid/probes.json +++ b/metadata/disclosures/prebid/probes.json @@ -22,7 +22,7 @@ "domains": [ { "domain": "*", - "use": "Temporary 'probing' cookies are written (and deleted) to determine the top-level domain; likewise, probes are temporarily written to local and sessionStorage to determine their availability" + "use": "Temporary 'probing' cookies are written (and deleted) to determine the top-level domain and availability of cookies; likewise, probes are temporarily written to local and sessionStorage to determine their availability" } ] } diff --git a/metadata/modules.json b/metadata/modules.json index b078a117e6e..60c9f672a99 100644 --- a/metadata/modules.json +++ b/metadata/modules.json @@ -43,6 +43,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "aceex", + "aliasOf": null, + "gvlid": 1387, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "acuityads", @@ -106,6 +113,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "adcluster", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "addefend", @@ -519,6 +533,13 @@ "gvlid": 1283, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "intlscoop", + "aliasOf": "adkernel", + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "admaru", @@ -568,6 +589,13 @@ "gvlid": 779, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "adrubi", + "aliasOf": "admatic", + "gvlid": 779, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "yobee", @@ -638,6 +666,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "adnimation", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "adnow", @@ -1163,6 +1198,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "apester", + "aliasOf": null, + "gvlid": 354, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "appStockSSP", @@ -2101,6 +2143,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "dpai", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "driftpixel", @@ -2290,6 +2339,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "floxis", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "fluct", @@ -2479,6 +2535,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "harion", + "aliasOf": null, + "gvlid": 1406, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "holid", @@ -2584,6 +2647,13 @@ "gvlid": 910, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "insurads", + "aliasOf": null, + "gvlid": 596, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "integr8", @@ -2738,6 +2808,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "leagueM", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "lemmadigital", @@ -2780,13 +2857,6 @@ "gvlid": 1358, "disclosureURL": null }, - { - "componentType": "bidder", - "componentName": "apester", - "aliasOf": "limelightDigital", - "gvlid": null, - "disclosureURL": null - }, { "componentType": "bidder", "componentName": "adsyield", @@ -2850,13 +2920,6 @@ "gvlid": null, "disclosureURL": null }, - { - "componentType": "bidder", - "componentName": "adnimation", - "aliasOf": "limelightDigital", - "gvlid": null, - "disclosureURL": null - }, { "componentType": "bidder", "componentName": "rtbdemand", @@ -3158,6 +3221,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "mile", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "minutemedia", @@ -3802,6 +3872,20 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "pubstack", + "aliasOf": null, + "gvlid": 1408, + "disclosureURL": null + }, + { + "componentType": "bidder", + "componentName": "pubstack_server", + "aliasOf": "pubstack", + "gvlid": 1408, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "pubx", @@ -3970,6 +4054,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "revantage", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "revcontent", @@ -4579,6 +4670,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "teqBlazeSalesAgent", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "theadx", @@ -4747,6 +4845,13 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "verben", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "viant", @@ -4985,6 +5090,13 @@ "gvlid": 25, "disclosureURL": null }, + { + "componentType": "bidder", + "componentName": "yaleo", + "aliasOf": null, + "gvlid": 783, + "disclosureURL": null + }, { "componentType": "bidder", "componentName": "yandex", @@ -5364,6 +5476,12 @@ "gvlid": null, "disclosureURL": null }, + { + "componentType": "rtd", + "componentName": "panxo", + "gvlid": null, + "disclosureURL": null + }, { "componentType": "rtd", "componentName": "permutive", @@ -5678,6 +5796,20 @@ "disclosureURL": null, "aliasOf": null }, + { + "componentType": "userId", + "componentName": "locId", + "gvlid": null, + "disclosureURL": null, + "aliasOf": null + }, + { + "componentType": "userId", + "componentName": "locid", + "gvlid": null, + "disclosureURL": null, + "aliasOf": "locId" + }, { "componentType": "userId", "componentName": "lockrAIMId", diff --git a/metadata/modules/33acrossBidAdapter.json b/metadata/modules/33acrossBidAdapter.json index 7c784ce23b2..79ecf25a705 100644 --- a/metadata/modules/33acrossBidAdapter.json +++ b/metadata/modules/33acrossBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://platform.33across.com/disclosures.json": { - "timestamp": "2026-01-28T16:29:58.218Z", + "timestamp": "2026-03-02T14:44:46.319Z", "disclosures": [] } }, diff --git a/metadata/modules/33acrossIdSystem.json b/metadata/modules/33acrossIdSystem.json index 08c9e5fdb3c..3adce4bba03 100644 --- a/metadata/modules/33acrossIdSystem.json +++ b/metadata/modules/33acrossIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://platform.33across.com/disclosures.json": { - "timestamp": "2026-01-28T16:29:58.314Z", + "timestamp": "2026-03-02T14:44:46.422Z", "disclosures": [] } }, diff --git a/metadata/modules/aceexBidAdapter.json b/metadata/modules/aceexBidAdapter.json new file mode 100644 index 00000000000..f443e609ec4 --- /dev/null +++ b/metadata/modules/aceexBidAdapter.json @@ -0,0 +1,18 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://aceex.io/tcf.json": { + "timestamp": "2026-03-02T14:44:46.425Z", + "disclosures": [] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "aceex", + "aliasOf": null, + "gvlid": 1387, + "disclosureURL": "https://aceex.io/tcf.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/acuityadsBidAdapter.json b/metadata/modules/acuityadsBidAdapter.json index 5c1719c2ce1..01786a901ea 100644 --- a/metadata/modules/acuityadsBidAdapter.json +++ b/metadata/modules/acuityadsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://privacy.acuityads.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:29:58.317Z", + "timestamp": "2026-03-02T14:44:46.471Z", "disclosures": [] } }, diff --git a/metadata/modules/adagioBidAdapter.json b/metadata/modules/adagioBidAdapter.json index b490d929e1a..728761cdcc3 100644 --- a/metadata/modules/adagioBidAdapter.json +++ b/metadata/modules/adagioBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adagio.io/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:29:58.354Z", + "timestamp": "2026-03-02T14:44:46.503Z", "disclosures": [] } }, diff --git a/metadata/modules/adagioRtdProvider.json b/metadata/modules/adagioRtdProvider.json index e604c3b2d9c..01aba8c973b 100644 --- a/metadata/modules/adagioRtdProvider.json +++ b/metadata/modules/adagioRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adagio.io/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:29:58.504Z", + "timestamp": "2026-03-02T14:44:46.575Z", "disclosures": [] } }, diff --git a/metadata/modules/adbroBidAdapter.json b/metadata/modules/adbroBidAdapter.json index 6b21766ca1d..c1607d5b2ea 100644 --- a/metadata/modules/adbroBidAdapter.json +++ b/metadata/modules/adbroBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tag.adbro.me/privacy/devicestorage.json": { - "timestamp": "2026-01-28T16:29:58.504Z", + "timestamp": "2026-03-02T14:44:46.575Z", "disclosures": [] } }, diff --git a/metadata/modules/adclusterBidAdapter.json b/metadata/modules/adclusterBidAdapter.json new file mode 100644 index 00000000000..72d44231bb6 --- /dev/null +++ b/metadata/modules/adclusterBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "adcluster", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/addefendBidAdapter.json b/metadata/modules/addefendBidAdapter.json index 0d880b30acc..1cd4c70fc97 100644 --- a/metadata/modules/addefendBidAdapter.json +++ b/metadata/modules/addefendBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.addefend.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:29:58.826Z", + "timestamp": "2026-03-02T14:44:46.894Z", "disclosures": [] } }, diff --git a/metadata/modules/adfBidAdapter.json b/metadata/modules/adfBidAdapter.json index fb6d19f8ad4..8e01eb95878 100644 --- a/metadata/modules/adfBidAdapter.json +++ b/metadata/modules/adfBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://site.adform.com/assets/devicestorage.json": { - "timestamp": "2026-01-28T16:29:59.445Z", + "timestamp": "2026-03-02T14:45:00.675Z", "disclosures": [] } }, diff --git a/metadata/modules/adfusionBidAdapter.json b/metadata/modules/adfusionBidAdapter.json index 57df8f4f68b..bec524db96d 100644 --- a/metadata/modules/adfusionBidAdapter.json +++ b/metadata/modules/adfusionBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://spicyrtb.com/static/iab-disclosure.json": { - "timestamp": "2026-01-28T16:29:59.445Z", + "timestamp": "2026-03-02T14:45:00.676Z", "disclosures": [] } }, diff --git a/metadata/modules/adheseBidAdapter.json b/metadata/modules/adheseBidAdapter.json index 907ed2be2df..341d5b1c818 100644 --- a/metadata/modules/adheseBidAdapter.json +++ b/metadata/modules/adheseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adhese.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:29:59.885Z", + "timestamp": "2026-03-02T14:45:01.041Z", "disclosures": [] } }, diff --git a/metadata/modules/adipoloBidAdapter.json b/metadata/modules/adipoloBidAdapter.json index 88388af4def..54ee67e7037 100644 --- a/metadata/modules/adipoloBidAdapter.json +++ b/metadata/modules/adipoloBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adipolo.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:00.155Z", + "timestamp": "2026-03-02T14:45:01.314Z", "disclosures": [] } }, diff --git a/metadata/modules/adkernelAdnBidAdapter.json b/metadata/modules/adkernelAdnBidAdapter.json index 29fbe50a428..0516f01d293 100644 --- a/metadata/modules/adkernelAdnBidAdapter.json +++ b/metadata/modules/adkernelAdnBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static.adkernel.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:00.288Z", + "timestamp": "2026-03-02T14:45:01.470Z", "disclosures": [ { "identifier": "adk_rtb_conv_id", diff --git a/metadata/modules/adkernelBidAdapter.json b/metadata/modules/adkernelBidAdapter.json index 3cefa08504a..8b11e6d7d24 100644 --- a/metadata/modules/adkernelBidAdapter.json +++ b/metadata/modules/adkernelBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static.adkernel.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:00.508Z", + "timestamp": "2026-03-02T14:45:01.554Z", "disclosures": [ { "identifier": "adk_rtb_conv_id", @@ -17,19 +17,19 @@ ] }, "https://data.converge-digital.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:00.508Z", + "timestamp": "2026-03-02T14:45:01.554Z", "disclosures": [] }, "https://spinx.biz/tcf-spinx.json": { - "timestamp": "2026-01-28T16:30:00.562Z", + "timestamp": "2026-03-02T14:45:01.604Z", "disclosures": [] }, "https://gdpr.memob.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:01.305Z", + "timestamp": "2026-03-02T14:45:02.320Z", "disclosures": [] }, "https://appmonsta.ai/DeviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:01.323Z", + "timestamp": "2026-03-02T14:45:02.337Z", "disclosures": [] } }, @@ -348,6 +348,13 @@ "aliasOf": "adkernel", "gvlid": 1283, "disclosureURL": "https://appmonsta.ai/DeviceStorageDisclosure.json" + }, + { + "componentType": "bidder", + "componentName": "intlscoop", + "aliasOf": "adkernel", + "gvlid": null, + "disclosureURL": null } ] } \ No newline at end of file diff --git a/metadata/modules/admaticBidAdapter.json b/metadata/modules/admaticBidAdapter.json index f44a99df523..ded364cbc31 100644 --- a/metadata/modules/admaticBidAdapter.json +++ b/metadata/modules/admaticBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static.admatic.de/iab-europe/tcfv2/disclosure.json": { - "timestamp": "2026-01-28T16:30:03.161Z", + "timestamp": "2026-03-02T14:45:02.895Z", "disclosures": [ { "identifier": "px_pbjs", @@ -12,7 +12,7 @@ ] }, "https://adtarget.com.tr/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:02.786Z", + "timestamp": "2026-03-02T14:45:02.895Z", "disclosures": [ { "identifier": "adt_pbjs", @@ -65,6 +65,13 @@ "gvlid": 779, "disclosureURL": "https://adtarget.com.tr/.well-known/deviceStorage.json" }, + { + "componentType": "bidder", + "componentName": "adrubi", + "aliasOf": "admatic", + "gvlid": 779, + "disclosureURL": "https://adtarget.com.tr/.well-known/deviceStorage.json" + }, { "componentType": "bidder", "componentName": "yobee", diff --git a/metadata/modules/admixerBidAdapter.json b/metadata/modules/admixerBidAdapter.json index f4aceb4271e..8f6d6f99397 100644 --- a/metadata/modules/admixerBidAdapter.json +++ b/metadata/modules/admixerBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://admixer.com/tcf.json": { - "timestamp": "2026-01-28T16:30:03.161Z", + "timestamp": "2026-03-02T14:45:02.896Z", "disclosures": [] } }, diff --git a/metadata/modules/admixerIdSystem.json b/metadata/modules/admixerIdSystem.json index 9e56d98f973..f8bd80f3bca 100644 --- a/metadata/modules/admixerIdSystem.json +++ b/metadata/modules/admixerIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://admixer.com/tcf.json": { - "timestamp": "2026-01-28T16:30:03.552Z", + "timestamp": "2026-03-02T14:45:03.276Z", "disclosures": [] } }, diff --git a/metadata/modules/adnimationBidAdapter.json b/metadata/modules/adnimationBidAdapter.json new file mode 100644 index 00000000000..7bb7fce194e --- /dev/null +++ b/metadata/modules/adnimationBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "adnimation", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/adnowBidAdapter.json b/metadata/modules/adnowBidAdapter.json index 85b183c233f..cb5aa129b20 100644 --- a/metadata/modules/adnowBidAdapter.json +++ b/metadata/modules/adnowBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adnow.com/vdsod.json": { - "timestamp": "2026-01-28T16:30:03.552Z", + "timestamp": "2026-03-02T14:45:03.276Z", "disclosures": [ { "identifier": "SC_unique_*", diff --git a/metadata/modules/adnuntiusBidAdapter.json b/metadata/modules/adnuntiusBidAdapter.json index faa59453320..c2a643ef408 100644 --- a/metadata/modules/adnuntiusBidAdapter.json +++ b/metadata/modules/adnuntiusBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://delivery.adnuntius.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:03.784Z", + "timestamp": "2026-03-02T14:45:16.546Z", "disclosures": [ { "identifier": "adn.metaData", diff --git a/metadata/modules/adnuntiusRtdProvider.json b/metadata/modules/adnuntiusRtdProvider.json index 88033c0bd3a..9c3af875f20 100644 --- a/metadata/modules/adnuntiusRtdProvider.json +++ b/metadata/modules/adnuntiusRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://delivery.adnuntius.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:04.118Z", + "timestamp": "2026-03-02T14:45:16.877Z", "disclosures": [ { "identifier": "adn.metaData", diff --git a/metadata/modules/adoceanBidAdapter.json b/metadata/modules/adoceanBidAdapter.json index 434185cfb11..c97b093663c 100644 --- a/metadata/modules/adoceanBidAdapter.json +++ b/metadata/modules/adoceanBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://gemius.com/media/documents/Gemius_SA_Vendor_Device_Storage.json": { - "timestamp": "2026-01-28T16:30:04.118Z", + "timestamp": "2026-03-02T14:45:16.878Z", "disclosures": [ { "identifier": "__gsyncs_gdpr", diff --git a/metadata/modules/adotBidAdapter.json b/metadata/modules/adotBidAdapter.json index 7e1e6a0aff6..9a38b9d66e3 100644 --- a/metadata/modules/adotBidAdapter.json +++ b/metadata/modules/adotBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.adotmob.com/tcf/tcf.json": { - "timestamp": "2026-01-28T16:30:04.676Z", + "timestamp": "2026-03-02T14:45:17.430Z", "disclosures": [] } }, diff --git a/metadata/modules/adponeBidAdapter.json b/metadata/modules/adponeBidAdapter.json index ffa30b608f0..7022a062e25 100644 --- a/metadata/modules/adponeBidAdapter.json +++ b/metadata/modules/adponeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adserver.adpone.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:04.714Z", + "timestamp": "2026-03-02T14:45:17.575Z", "disclosures": [] } }, diff --git a/metadata/modules/adqueryBidAdapter.json b/metadata/modules/adqueryBidAdapter.json index 9525503e59b..6ee1ee7d899 100644 --- a/metadata/modules/adqueryBidAdapter.json +++ b/metadata/modules/adqueryBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://api.adquery.io/tcf/adQuery.json": { - "timestamp": "2026-01-28T16:30:04.745Z", + "timestamp": "2026-03-02T14:45:17.832Z", "disclosures": [] } }, diff --git a/metadata/modules/adqueryIdSystem.json b/metadata/modules/adqueryIdSystem.json index cc0f9edaf73..d97e79287da 100644 --- a/metadata/modules/adqueryIdSystem.json +++ b/metadata/modules/adqueryIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://api.adquery.io/tcf/adQuery.json": { - "timestamp": "2026-01-28T16:30:05.099Z", + "timestamp": "2026-03-02T14:45:18.165Z", "disclosures": [] } }, diff --git a/metadata/modules/adrinoBidAdapter.json b/metadata/modules/adrinoBidAdapter.json index 1b11ddd4322..1683ae8d010 100644 --- a/metadata/modules/adrinoBidAdapter.json +++ b/metadata/modules/adrinoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.adrino.cloud/iab/device-storage.json": { - "timestamp": "2026-01-28T16:30:05.100Z", + "timestamp": "2026-03-02T14:45:18.166Z", "disclosures": [] } }, diff --git a/metadata/modules/ads_interactiveBidAdapter.json b/metadata/modules/ads_interactiveBidAdapter.json index 186d5188d3b..c0bcc3c0438 100644 --- a/metadata/modules/ads_interactiveBidAdapter.json +++ b/metadata/modules/ads_interactiveBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adsinteractive.com/vendor.json": { - "timestamp": "2026-01-28T16:30:05.144Z", + "timestamp": "2026-03-02T14:45:18.257Z", "disclosures": [] } }, diff --git a/metadata/modules/adtargetBidAdapter.json b/metadata/modules/adtargetBidAdapter.json index 5ca832a5cfb..643548e6a49 100644 --- a/metadata/modules/adtargetBidAdapter.json +++ b/metadata/modules/adtargetBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adtarget.com.tr/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:05.446Z", + "timestamp": "2026-03-02T14:45:18.549Z", "disclosures": [ { "identifier": "adt_pbjs", diff --git a/metadata/modules/adtelligentBidAdapter.json b/metadata/modules/adtelligentBidAdapter.json index 5df3a013203..68c149946c6 100644 --- a/metadata/modules/adtelligentBidAdapter.json +++ b/metadata/modules/adtelligentBidAdapter.json @@ -2,11 +2,11 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adtelligent.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:05.446Z", + "timestamp": "2026-03-02T14:45:18.549Z", "disclosures": [] }, "https://www.selectmedia.asia/gdpr/devicestorage.json": { - "timestamp": "2026-01-28T16:30:05.465Z", + "timestamp": "2026-03-02T14:45:18.568Z", "disclosures": [ { "identifier": "waterFallCacheAnsKey_*", @@ -81,7 +81,7 @@ ] }, "https://orangeclickmedia.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:05.651Z", + "timestamp": "2026-03-02T14:45:31.321Z", "disclosures": [] } }, diff --git a/metadata/modules/adtelligentIdSystem.json b/metadata/modules/adtelligentIdSystem.json index 4793bd2971a..63773fb0465 100644 --- a/metadata/modules/adtelligentIdSystem.json +++ b/metadata/modules/adtelligentIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adtelligent.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:05.794Z", + "timestamp": "2026-03-02T14:45:31.395Z", "disclosures": [] } }, diff --git a/metadata/modules/aduptechBidAdapter.json b/metadata/modules/aduptechBidAdapter.json index 763a2faa1b7..63a0f554c7f 100644 --- a/metadata/modules/aduptechBidAdapter.json +++ b/metadata/modules/aduptechBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s.d.adup-tech.com/gdpr/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:05.795Z", + "timestamp": "2026-03-02T14:45:31.395Z", "disclosures": [] } }, diff --git a/metadata/modules/adyoulikeBidAdapter.json b/metadata/modules/adyoulikeBidAdapter.json index ad36769e5f0..80d9bc14b7e 100644 --- a/metadata/modules/adyoulikeBidAdapter.json +++ b/metadata/modules/adyoulikeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adyoulike.com/deviceStorageDisclosureURL.json": { - "timestamp": "2026-01-28T16:30:05.815Z", + "timestamp": "2026-03-02T14:45:31.420Z", "disclosures": [] } }, diff --git a/metadata/modules/airgridRtdProvider.json b/metadata/modules/airgridRtdProvider.json index d490880b416..e127fd2d00b 100644 --- a/metadata/modules/airgridRtdProvider.json +++ b/metadata/modules/airgridRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.wearemiq.com/privacy-and-compliance/devicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:06.273Z", + "timestamp": "2026-03-02T14:45:31.871Z", "disclosures": [] } }, diff --git a/metadata/modules/alkimiBidAdapter.json b/metadata/modules/alkimiBidAdapter.json index f80e84a7d63..a9638ab0a47 100644 --- a/metadata/modules/alkimiBidAdapter.json +++ b/metadata/modules/alkimiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://d1xjh92lb8fey3.cloudfront.net/tcf/alkimi_exchange_tcf.json": { - "timestamp": "2026-01-28T16:30:06.319Z", + "timestamp": "2026-03-02T14:45:31.902Z", "disclosures": [] } }, diff --git a/metadata/modules/allegroBidAdapter.json b/metadata/modules/allegroBidAdapter.json index 0bb0131e96f..0d631041437 100644 --- a/metadata/modules/allegroBidAdapter.json +++ b/metadata/modules/allegroBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.allegrostatic.com/dsp-tcf-external/device-storage.json": { - "timestamp": "2026-01-28T16:30:06.612Z", + "timestamp": "2026-03-02T14:45:32.202Z", "disclosures": [] } }, diff --git a/metadata/modules/amxBidAdapter.json b/metadata/modules/amxBidAdapter.json index 8de34154ecc..8a4900eb3fb 100644 --- a/metadata/modules/amxBidAdapter.json +++ b/metadata/modules/amxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.a-mo.net/tcf/device-storage.json": { - "timestamp": "2026-01-28T16:30:07.054Z", + "timestamp": "2026-03-02T14:45:32.667Z", "disclosures": [] } }, diff --git a/metadata/modules/amxIdSystem.json b/metadata/modules/amxIdSystem.json index 1a8270a07dd..a204078442a 100644 --- a/metadata/modules/amxIdSystem.json +++ b/metadata/modules/amxIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.a-mo.net/tcf/device-storage.json": { - "timestamp": "2026-01-28T16:30:07.197Z", + "timestamp": "2026-03-02T14:45:32.757Z", "disclosures": [] } }, diff --git a/metadata/modules/aniviewBidAdapter.json b/metadata/modules/aniviewBidAdapter.json index e2d0cb92554..0bc1a7c7752 100644 --- a/metadata/modules/aniviewBidAdapter.json +++ b/metadata/modules/aniviewBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://player.aniview.com/gdpr/gdpr.json": { - "timestamp": "2026-01-28T16:30:07.197Z", + "timestamp": "2026-03-02T14:45:32.758Z", "disclosures": [ { "identifier": "av_*", diff --git a/metadata/modules/anonymisedRtdProvider.json b/metadata/modules/anonymisedRtdProvider.json index 3da9ac7b85c..7593b8bcb11 100644 --- a/metadata/modules/anonymisedRtdProvider.json +++ b/metadata/modules/anonymisedRtdProvider.json @@ -1,8 +1,8 @@ { "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { - "https://static.anonymised.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:07.304Z", + "https://cdn1.anonymised.io/deviceStorage.json": { + "timestamp": "2026-03-02T14:45:32.828Z", "disclosures": [ { "identifier": "oidc.user*", @@ -67,7 +67,7 @@ "componentType": "rtd", "componentName": "anonymised", "gvlid": 1116, - "disclosureURL": "https://static.anonymised.io/deviceStorage.json" + "disclosureURL": "https://cdn1.anonymised.io/deviceStorage.json" } ] } \ No newline at end of file diff --git a/metadata/modules/apesterBidAdapter.json b/metadata/modules/apesterBidAdapter.json new file mode 100644 index 00000000000..372e0ba6a78 --- /dev/null +++ b/metadata/modules/apesterBidAdapter.json @@ -0,0 +1,18 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://apester.com/deviceStorage.json": { + "timestamp": "2026-03-02T14:45:33.047Z", + "disclosures": [] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "apester", + "aliasOf": null, + "gvlid": 354, + "disclosureURL": "https://apester.com/deviceStorage.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/appStockSSPBidAdapter.json b/metadata/modules/appStockSSPBidAdapter.json index 8bd90c00e58..8d113568028 100644 --- a/metadata/modules/appStockSSPBidAdapter.json +++ b/metadata/modules/appStockSSPBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://app-stock.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:07.420Z", + "timestamp": "2026-03-02T14:45:33.167Z", "disclosures": [] } }, diff --git a/metadata/modules/appierBidAdapter.json b/metadata/modules/appierBidAdapter.json index 2f0f4655a71..bc805982843 100644 --- a/metadata/modules/appierBidAdapter.json +++ b/metadata/modules/appierBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.appier.com/deviceStorage2025.json": { - "timestamp": "2026-01-28T16:30:07.455Z", + "timestamp": "2026-03-02T14:45:33.203Z", "disclosures": [ { "identifier": "_atrk_ssid", diff --git a/metadata/modules/appnexusBidAdapter.json b/metadata/modules/appnexusBidAdapter.json index ca815263571..59027a399d7 100644 --- a/metadata/modules/appnexusBidAdapter.json +++ b/metadata/modules/appnexusBidAdapter.json @@ -2,19 +2,19 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://acdn.adnxs.com/gvl/1d/xandrdevicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:08.134Z", + "timestamp": "2026-03-02T14:45:33.960Z", "disclosures": [] }, "https://beintoo-support.b-cdn.net/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:07.591Z", + "timestamp": "2026-03-02T14:45:33.279Z", "disclosures": [] }, "https://projectagora.net/1032_deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:07.694Z", + "timestamp": "2026-03-02T14:45:33.420Z", "disclosures": [] }, "https://adzymic.com/tcf.json": { - "timestamp": "2026-01-28T16:30:08.134Z", + "timestamp": "2026-03-02T14:45:33.960Z", "disclosures": [] } }, diff --git a/metadata/modules/appushBidAdapter.json b/metadata/modules/appushBidAdapter.json index b74c3d9b2e8..15019d11110 100644 --- a/metadata/modules/appushBidAdapter.json +++ b/metadata/modules/appushBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.thebiding.com/disclosures.json": { - "timestamp": "2026-01-28T16:30:08.156Z", + "timestamp": "2026-03-02T14:45:33.989Z", "disclosures": [] } }, diff --git a/metadata/modules/apsBidAdapter.json b/metadata/modules/apsBidAdapter.json index 3ddca493ec1..7132ee483e9 100644 --- a/metadata/modules/apsBidAdapter.json +++ b/metadata/modules/apsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://m.media-amazon.com/images/G/01/adprefs/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:08.218Z", + "timestamp": "2026-03-02T14:45:34.055Z", "disclosures": [ { "identifier": "vendor-id", diff --git a/metadata/modules/apstreamBidAdapter.json b/metadata/modules/apstreamBidAdapter.json index b45081cbc64..b7a2fb2671d 100644 --- a/metadata/modules/apstreamBidAdapter.json +++ b/metadata/modules/apstreamBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sak.userreport.com/tcf.json": { - "timestamp": "2026-01-28T16:30:08.230Z", + "timestamp": "2026-03-02T14:45:34.071Z", "disclosures": [ { "identifier": "apr_dsu", diff --git a/metadata/modules/audiencerunBidAdapter.json b/metadata/modules/audiencerunBidAdapter.json index 561717d5ac0..ad7d2d71fc5 100644 --- a/metadata/modules/audiencerunBidAdapter.json +++ b/metadata/modules/audiencerunBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.audiencerun.com/tcf.json": { - "timestamp": "2026-01-28T16:30:08.251Z", + "timestamp": "2026-03-02T14:45:34.115Z", "disclosures": [] } }, diff --git a/metadata/modules/axisBidAdapter.json b/metadata/modules/axisBidAdapter.json index 97d8889684e..33ade7a617c 100644 --- a/metadata/modules/axisBidAdapter.json +++ b/metadata/modules/axisBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://axis-marketplace.com/tcf.json": { - "timestamp": "2026-01-28T16:30:08.288Z", + "timestamp": "2026-03-02T14:45:34.167Z", "disclosures": [] } }, diff --git a/metadata/modules/azerionedgeRtdProvider.json b/metadata/modules/azerionedgeRtdProvider.json index 138bb4cf730..198266cb6ac 100644 --- a/metadata/modules/azerionedgeRtdProvider.json +++ b/metadata/modules/azerionedgeRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sellers.improvedigital.com/tcf-cookies.json": { - "timestamp": "2026-01-28T16:30:08.325Z", + "timestamp": "2026-03-02T14:45:34.210Z", "disclosures": [ { "identifier": "tuuid", diff --git a/metadata/modules/beachfrontBidAdapter.json b/metadata/modules/beachfrontBidAdapter.json index d9ea10bb0eb..b7f18cad4eb 100644 --- a/metadata/modules/beachfrontBidAdapter.json +++ b/metadata/modules/beachfrontBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.seedtag.com/vendor.json": { - "timestamp": "2026-01-28T16:30:08.359Z", + "timestamp": "2026-03-02T14:45:34.236Z", "disclosures": [] } }, diff --git a/metadata/modules/beopBidAdapter.json b/metadata/modules/beopBidAdapter.json index 7de553c3356..84b4ecc7f33 100644 --- a/metadata/modules/beopBidAdapter.json +++ b/metadata/modules/beopBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://beop.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:08.381Z", + "timestamp": "2026-03-02T14:45:34.257Z", "disclosures": [] } }, diff --git a/metadata/modules/betweenBidAdapter.json b/metadata/modules/betweenBidAdapter.json index cdeb282e76d..b48dadd84d0 100644 --- a/metadata/modules/betweenBidAdapter.json +++ b/metadata/modules/betweenBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://en.betweenx.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:08.501Z", + "timestamp": "2026-03-02T14:45:34.379Z", "disclosures": [] } }, diff --git a/metadata/modules/bidfuseBidAdapter.json b/metadata/modules/bidfuseBidAdapter.json index e9f10a2af75..cb5dc975164 100644 --- a/metadata/modules/bidfuseBidAdapter.json +++ b/metadata/modules/bidfuseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bidfuse.com/disclosure.json": { - "timestamp": "2026-01-28T16:30:08.568Z", + "timestamp": "2026-03-02T14:45:34.436Z", "disclosures": [] } }, diff --git a/metadata/modules/bidmaticBidAdapter.json b/metadata/modules/bidmaticBidAdapter.json index c698dd1c7e1..320c69b6e66 100644 --- a/metadata/modules/bidmaticBidAdapter.json +++ b/metadata/modules/bidmaticBidAdapter.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bidmatic.io/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:09.193Z", - "disclosures": [] + "timestamp": "2026-03-02T14:45:34.611Z", + "disclosures": null } }, "components": [ diff --git a/metadata/modules/bidtheatreBidAdapter.json b/metadata/modules/bidtheatreBidAdapter.json index f8747a74d23..987e79d876e 100644 --- a/metadata/modules/bidtheatreBidAdapter.json +++ b/metadata/modules/bidtheatreBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://privacy.bidtheatre.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:09.243Z", + "timestamp": "2026-03-02T14:45:34.658Z", "disclosures": [] } }, diff --git a/metadata/modules/bliinkBidAdapter.json b/metadata/modules/bliinkBidAdapter.json index 2daef968201..9ae146cb5de 100644 --- a/metadata/modules/bliinkBidAdapter.json +++ b/metadata/modules/bliinkBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bliink.io/disclosures.json": { - "timestamp": "2026-01-28T16:30:09.554Z", + "timestamp": "2026-03-02T14:45:34.957Z", "disclosures": [] } }, diff --git a/metadata/modules/blockthroughBidAdapter.json b/metadata/modules/blockthroughBidAdapter.json index b6e60f793e3..b3c53c81f31 100644 --- a/metadata/modules/blockthroughBidAdapter.json +++ b/metadata/modules/blockthroughBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://blockthrough.com/tcf_disclosures.json": { - "timestamp": "2026-01-28T16:30:09.898Z", + "timestamp": "2026-03-02T14:45:35.252Z", "disclosures": [ { "identifier": "BT_AA_DETECTION", diff --git a/metadata/modules/blueBidAdapter.json b/metadata/modules/blueBidAdapter.json index d5459ddd030..fdefc12b8e7 100644 --- a/metadata/modules/blueBidAdapter.json +++ b/metadata/modules/blueBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://getblue.io/iab/iab.json": { - "timestamp": "2026-01-28T16:30:10.177Z", + "timestamp": "2026-03-02T14:45:35.438Z", "disclosures": [] } }, diff --git a/metadata/modules/bmsBidAdapter.json b/metadata/modules/bmsBidAdapter.json index a7f11357ec6..59d3a1914dc 100644 --- a/metadata/modules/bmsBidAdapter.json +++ b/metadata/modules/bmsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bluems.com/iab.json": { - "timestamp": "2026-01-28T16:30:10.533Z", + "timestamp": "2026-03-02T14:45:35.784Z", "disclosures": [] } }, diff --git a/metadata/modules/boldwinBidAdapter.json b/metadata/modules/boldwinBidAdapter.json index 2e6fbbf4f05..e8f694fd2b9 100644 --- a/metadata/modules/boldwinBidAdapter.json +++ b/metadata/modules/boldwinBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://magav.videowalldirect.com/iab/videowalldirectiab.json": { - "timestamp": "2026-01-28T16:30:10.546Z", + "timestamp": "2026-03-02T14:45:35.801Z", "disclosures": [] } }, diff --git a/metadata/modules/bridBidAdapter.json b/metadata/modules/bridBidAdapter.json index 3141704c3cf..4475c15ed3a 100644 --- a/metadata/modules/bridBidAdapter.json +++ b/metadata/modules/bridBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://target-video.com/vendors-device-storage-and-operational-disclosures.json": { - "timestamp": "2026-01-28T16:30:10.571Z", + "timestamp": "2026-03-02T14:45:35.828Z", "disclosures": [ { "identifier": "brid_location", diff --git a/metadata/modules/browsiBidAdapter.json b/metadata/modules/browsiBidAdapter.json index 4983eb994cd..ddc532d4e32 100644 --- a/metadata/modules/browsiBidAdapter.json +++ b/metadata/modules/browsiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.browsiprod.com/ads/tcf.json": { - "timestamp": "2026-01-28T16:30:10.712Z", + "timestamp": "2026-03-02T14:45:35.966Z", "disclosures": [] } }, diff --git a/metadata/modules/bucksenseBidAdapter.json b/metadata/modules/bucksenseBidAdapter.json index 5756973a60a..571e8dac8d9 100644 --- a/metadata/modules/bucksenseBidAdapter.json +++ b/metadata/modules/bucksenseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://j.bksnimages.com/iab/devsto02.json": { - "timestamp": "2026-01-28T16:30:10.730Z", + "timestamp": "2026-03-02T14:45:36.025Z", "disclosures": [] } }, diff --git a/metadata/modules/carodaBidAdapter.json b/metadata/modules/carodaBidAdapter.json index bf06a9d157f..06cedda2cbb 100644 --- a/metadata/modules/carodaBidAdapter.json +++ b/metadata/modules/carodaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn2.caroda.io/tcfvds/2022-05-17/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:10.790Z", + "timestamp": "2026-03-02T14:45:36.084Z", "disclosures": [] } }, diff --git a/metadata/modules/categoryTranslation.json b/metadata/modules/categoryTranslation.json index 62d8ea2cf73..1b8ecd5185e 100644 --- a/metadata/modules/categoryTranslation.json +++ b/metadata/modules/categoryTranslation.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/categoryTranslation.json": { - "timestamp": "2026-01-28T16:29:58.215Z", + "timestamp": "2026-03-02T14:44:46.317Z", "disclosures": [ { "identifier": "iabToFwMappingkey", diff --git a/metadata/modules/ceeIdSystem.json b/metadata/modules/ceeIdSystem.json index 9d6ee591a78..414cf9f61c3 100644 --- a/metadata/modules/ceeIdSystem.json +++ b/metadata/modules/ceeIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ssp.wp.pl/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:11.083Z", + "timestamp": "2026-03-02T14:45:36.379Z", "disclosures": null } }, diff --git a/metadata/modules/chromeAiRtdProvider.json b/metadata/modules/chromeAiRtdProvider.json index f01c1535e6c..0374f04c2e3 100644 --- a/metadata/modules/chromeAiRtdProvider.json +++ b/metadata/modules/chromeAiRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/modules/chromeAiRtdProvider.json": { - "timestamp": "2026-01-28T16:30:11.410Z", + "timestamp": "2026-03-02T14:45:36.729Z", "disclosures": [ { "identifier": "chromeAi_detected_data", diff --git a/metadata/modules/clickioBidAdapter.json b/metadata/modules/clickioBidAdapter.json index 098d2ef463b..ec57e47521f 100644 --- a/metadata/modules/clickioBidAdapter.json +++ b/metadata/modules/clickioBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://o.clickiocdn.com/tcf_storage_info.json": { - "timestamp": "2026-01-28T16:30:11.411Z", + "timestamp": "2026-03-02T14:45:36.730Z", "disclosures": [] } }, diff --git a/metadata/modules/compassBidAdapter.json b/metadata/modules/compassBidAdapter.json index 0e34d3b794e..145961029d1 100644 --- a/metadata/modules/compassBidAdapter.json +++ b/metadata/modules/compassBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.marphezis.com/tcf-vendor-disclosures.json": { - "timestamp": "2026-01-28T16:30:11.830Z", + "timestamp": "2026-03-02T14:45:37.148Z", "disclosures": [] } }, diff --git a/metadata/modules/conceptxBidAdapter.json b/metadata/modules/conceptxBidAdapter.json index a8dc49de2f9..41d01c918e0 100644 --- a/metadata/modules/conceptxBidAdapter.json +++ b/metadata/modules/conceptxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cncptx.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:11.853Z", + "timestamp": "2026-03-02T14:45:37.166Z", "disclosures": [] } }, diff --git a/metadata/modules/connatixBidAdapter.json b/metadata/modules/connatixBidAdapter.json index ceff6354d6a..a1b7a772220 100644 --- a/metadata/modules/connatixBidAdapter.json +++ b/metadata/modules/connatixBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://connatix.com/iab-tcf-disclosure.json": { - "timestamp": "2026-01-28T16:30:11.876Z", + "timestamp": "2026-03-02T14:45:37.190Z", "disclosures": [ { "identifier": "cnx_userId", diff --git a/metadata/modules/connectIdSystem.json b/metadata/modules/connectIdSystem.json index fc825b87474..0cd76902e9b 100644 --- a/metadata/modules/connectIdSystem.json +++ b/metadata/modules/connectIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://meta.legal.yahoo.com/iab-tcf/v2/device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:11.964Z", + "timestamp": "2026-03-02T14:45:37.270Z", "disclosures": [ { "identifier": "vmcid", diff --git a/metadata/modules/connectadBidAdapter.json b/metadata/modules/connectadBidAdapter.json index 449b80e8442..96bc8e141d6 100644 --- a/metadata/modules/connectadBidAdapter.json +++ b/metadata/modules/connectadBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.connectad.io/tcf_storage_info.json": { - "timestamp": "2026-01-28T16:30:11.985Z", + "timestamp": "2026-03-02T14:45:37.290Z", "disclosures": [] } }, diff --git a/metadata/modules/contentexchangeBidAdapter.json b/metadata/modules/contentexchangeBidAdapter.json index 2fe9de26b24..7b5a61930c9 100644 --- a/metadata/modules/contentexchangeBidAdapter.json +++ b/metadata/modules/contentexchangeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://hb.contentexchange.me/template/device_storage.json": { - "timestamp": "2026-01-28T16:30:12.429Z", + "timestamp": "2026-03-02T14:45:37.325Z", "disclosures": null } }, diff --git a/metadata/modules/conversantBidAdapter.json b/metadata/modules/conversantBidAdapter.json index 61dd65570fe..5999b1b9c9a 100644 --- a/metadata/modules/conversantBidAdapter.json +++ b/metadata/modules/conversantBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s-usweb.dotomi.com/assets/js/taggy-js/2.18.9/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:12.505Z", + "timestamp": "2026-03-02T14:45:37.366Z", "disclosures": [ { "identifier": "dtm_status", diff --git a/metadata/modules/copper6sspBidAdapter.json b/metadata/modules/copper6sspBidAdapter.json index 962b5946cd8..1bc771d2901 100644 --- a/metadata/modules/copper6sspBidAdapter.json +++ b/metadata/modules/copper6sspBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ssp.copper6.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:12.542Z", + "timestamp": "2026-03-02T14:45:37.458Z", "disclosures": [] } }, diff --git a/metadata/modules/cpmstarBidAdapter.json b/metadata/modules/cpmstarBidAdapter.json index 253fd1b3b2d..255976fa486 100644 --- a/metadata/modules/cpmstarBidAdapter.json +++ b/metadata/modules/cpmstarBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.aditude.com/storageaccess.json": { - "timestamp": "2026-01-28T16:30:12.576Z", + "timestamp": "2026-03-02T14:45:37.500Z", "disclosures": [] } }, diff --git a/metadata/modules/criteoBidAdapter.json b/metadata/modules/criteoBidAdapter.json index 8d62de75bc0..fb94d78e961 100644 --- a/metadata/modules/criteoBidAdapter.json +++ b/metadata/modules/criteoBidAdapter.json @@ -1,8 +1,8 @@ { "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { - "https://privacy.criteo.com/iab-europe/tcfv2/disclosure": { - "timestamp": "2026-01-28T16:30:12.617Z", + "https://privacy.criteo.com/iab-europe/tcfv2/disclosure.json": { + "timestamp": "2026-03-02T14:45:37.599Z", "disclosures": [ { "identifier": "criteo_fast_bid", @@ -69,7 +69,7 @@ "componentName": "criteo", "aliasOf": null, "gvlid": 91, - "disclosureURL": "https://privacy.criteo.com/iab-europe/tcfv2/disclosure" + "disclosureURL": "https://privacy.criteo.com/iab-europe/tcfv2/disclosure.json" } ] } \ No newline at end of file diff --git a/metadata/modules/criteoIdSystem.json b/metadata/modules/criteoIdSystem.json index 6a64ec8205c..d0e56b65ba1 100644 --- a/metadata/modules/criteoIdSystem.json +++ b/metadata/modules/criteoIdSystem.json @@ -1,8 +1,8 @@ { "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { - "https://privacy.criteo.com/iab-europe/tcfv2/disclosure": { - "timestamp": "2026-01-28T16:30:12.634Z", + "https://privacy.criteo.com/iab-europe/tcfv2/disclosure.json": { + "timestamp": "2026-03-02T14:45:37.624Z", "disclosures": [ { "identifier": "criteo_fast_bid", @@ -68,7 +68,7 @@ "componentType": "userId", "componentName": "criteo", "gvlid": 91, - "disclosureURL": "https://privacy.criteo.com/iab-europe/tcfv2/disclosure", + "disclosureURL": "https://privacy.criteo.com/iab-europe/tcfv2/disclosure.json", "aliasOf": null } ] diff --git a/metadata/modules/cwireBidAdapter.json b/metadata/modules/cwireBidAdapter.json index c7a9dc12ec0..265357a9c7f 100644 --- a/metadata/modules/cwireBidAdapter.json +++ b/metadata/modules/cwireBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.cwi.re/artifacts/iab/iab.json": { - "timestamp": "2026-01-28T16:30:12.634Z", + "timestamp": "2026-03-02T14:45:37.625Z", "disclosures": [] } }, diff --git a/metadata/modules/czechAdIdSystem.json b/metadata/modules/czechAdIdSystem.json index b6bd886fdd5..7a945949fe0 100644 --- a/metadata/modules/czechAdIdSystem.json +++ b/metadata/modules/czechAdIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cpex.cz/storagedisclosure.json": { - "timestamp": "2026-01-28T16:30:12.660Z", + "timestamp": "2026-03-02T14:45:37.988Z", "disclosures": [] } }, diff --git a/metadata/modules/dailymotionBidAdapter.json b/metadata/modules/dailymotionBidAdapter.json index bccf9e38e58..6779bc9b8a9 100644 --- a/metadata/modules/dailymotionBidAdapter.json +++ b/metadata/modules/dailymotionBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://statics.dmcdn.net/a/vds.json": { - "timestamp": "2026-01-28T16:30:13.069Z", + "timestamp": "2026-03-02T14:45:38.394Z", "disclosures": [ { "identifier": "uid_dm", diff --git a/metadata/modules/debugging.json b/metadata/modules/debugging.json index 63533ff21b1..d8035174738 100644 --- a/metadata/modules/debugging.json +++ b/metadata/modules/debugging.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/debugging.json": { - "timestamp": "2026-01-28T16:29:58.214Z", + "timestamp": "2026-03-02T14:44:46.316Z", "disclosures": [ { "identifier": "__*_debugging__", diff --git a/metadata/modules/deepintentBidAdapter.json b/metadata/modules/deepintentBidAdapter.json index 0328b249ca0..f9698c4095a 100644 --- a/metadata/modules/deepintentBidAdapter.json +++ b/metadata/modules/deepintentBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.deepintent.com/iabeurope_vendor_disclosures.json": { - "timestamp": "2026-01-28T16:30:13.171Z", + "timestamp": "2026-02-23T16:45:55.384Z", "disclosures": [] } }, diff --git a/metadata/modules/defineMediaBidAdapter.json b/metadata/modules/defineMediaBidAdapter.json index 4bdab1c5991..cc0c299d4f7 100644 --- a/metadata/modules/defineMediaBidAdapter.json +++ b/metadata/modules/defineMediaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://definemedia.de/tcf/deviceStorageDisclosureURL.json": { - "timestamp": "2026-01-28T16:30:13.310Z", + "timestamp": "2026-03-02T14:45:38.686Z", "disclosures": [ { "identifier": "conative$dataGathering$Adex", diff --git a/metadata/modules/deltaprojectsBidAdapter.json b/metadata/modules/deltaprojectsBidAdapter.json index 421bf1dc518..ca2f76b4695 100644 --- a/metadata/modules/deltaprojectsBidAdapter.json +++ b/metadata/modules/deltaprojectsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.de17a.com/policy/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:13.748Z", + "timestamp": "2026-03-02T14:45:39.098Z", "disclosures": [] } }, diff --git a/metadata/modules/dianomiBidAdapter.json b/metadata/modules/dianomiBidAdapter.json index 8a1c226d253..1ee3130984b 100644 --- a/metadata/modules/dianomiBidAdapter.json +++ b/metadata/modules/dianomiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.dianomi.com/device_storage.json": { - "timestamp": "2026-01-28T16:30:14.164Z", + "timestamp": "2026-03-02T14:45:44.672Z", "disclosures": [] } }, diff --git a/metadata/modules/digitalMatterBidAdapter.json b/metadata/modules/digitalMatterBidAdapter.json index 3f71ed4c5e4..8d8e30c4102 100644 --- a/metadata/modules/digitalMatterBidAdapter.json +++ b/metadata/modules/digitalMatterBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://digitalmatter.ai/disclosures.json": { - "timestamp": "2026-01-28T16:30:14.165Z", + "timestamp": "2026-03-02T14:45:44.672Z", "disclosures": [] } }, diff --git a/metadata/modules/distroscaleBidAdapter.json b/metadata/modules/distroscaleBidAdapter.json index 7bc7a6fbaa2..b19604b5704 100644 --- a/metadata/modules/distroscaleBidAdapter.json +++ b/metadata/modules/distroscaleBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://a.jsrdn.com/tcf/tcf-vendor-disclosure.json": { - "timestamp": "2026-01-28T16:30:14.541Z", + "timestamp": "2026-03-02T14:45:45.048Z", "disclosures": [] } }, diff --git a/metadata/modules/docereeAdManagerBidAdapter.json b/metadata/modules/docereeAdManagerBidAdapter.json index 2ef6917eac2..676eab6e3c8 100644 --- a/metadata/modules/docereeAdManagerBidAdapter.json +++ b/metadata/modules/docereeAdManagerBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://doceree.com/.well-known/iab/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:14.843Z", + "timestamp": "2026-03-02T14:45:45.334Z", "disclosures": [] } }, diff --git a/metadata/modules/docereeBidAdapter.json b/metadata/modules/docereeBidAdapter.json index f24747edfe1..14a0769efca 100644 --- a/metadata/modules/docereeBidAdapter.json +++ b/metadata/modules/docereeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://doceree.com/.well-known/iab/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:15.632Z", + "timestamp": "2026-03-02T14:45:46.086Z", "disclosures": [] } }, diff --git a/metadata/modules/dpaiBidAdapter.json b/metadata/modules/dpaiBidAdapter.json new file mode 100644 index 00000000000..901b09a3355 --- /dev/null +++ b/metadata/modules/dpaiBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "dpai", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/dspxBidAdapter.json b/metadata/modules/dspxBidAdapter.json index 18aa462c75c..579ccaef7ac 100644 --- a/metadata/modules/dspxBidAdapter.json +++ b/metadata/modules/dspxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.adtech.app/gen/deviceStorageDisclosure/os.json": { - "timestamp": "2026-01-28T16:30:15.633Z", + "timestamp": "2026-03-02T14:45:46.087Z", "disclosures": [] } }, diff --git a/metadata/modules/e_volutionBidAdapter.json b/metadata/modules/e_volutionBidAdapter.json index 9b0da76504c..1410a3e4917 100644 --- a/metadata/modules/e_volutionBidAdapter.json +++ b/metadata/modules/e_volutionBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://e-volution.ai/file.json": { - "timestamp": "2026-01-28T16:30:16.296Z", + "timestamp": "2026-03-02T14:45:46.760Z", "disclosures": [] } }, diff --git a/metadata/modules/edge226BidAdapter.json b/metadata/modules/edge226BidAdapter.json index e222f7a1ae2..58cc40d3ace 100644 --- a/metadata/modules/edge226BidAdapter.json +++ b/metadata/modules/edge226BidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.serveteck.com/cdn_storage/tcf/tcf.json?a=1.io": { - "timestamp": "2026-01-28T16:30:16.642Z", + "timestamp": "2026-03-02T14:45:47.084Z", "disclosures": [] } }, diff --git a/metadata/modules/empowerBidAdapter.json b/metadata/modules/empowerBidAdapter.json index b437207d105..5b8c1e60d93 100644 --- a/metadata/modules/empowerBidAdapter.json +++ b/metadata/modules/empowerBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.empower.net/vendor/vendor.json": { - "timestamp": "2026-01-28T16:30:16.693Z", + "timestamp": "2026-03-02T14:45:47.136Z", "disclosures": [] } }, diff --git a/metadata/modules/equativBidAdapter.json b/metadata/modules/equativBidAdapter.json index 66796571f18..a618d1b2dd7 100644 --- a/metadata/modules/equativBidAdapter.json +++ b/metadata/modules/equativBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://apps.smartadserver.com/device-storage-disclosures/equativDeviceStorageDisclosures.json": { - "timestamp": "2026-01-28T16:30:16.716Z", + "timestamp": "2026-03-02T14:45:47.169Z", "disclosures": [] } }, diff --git a/metadata/modules/eskimiBidAdapter.json b/metadata/modules/eskimiBidAdapter.json index 22dc25ff479..8908f454cef 100644 --- a/metadata/modules/eskimiBidAdapter.json +++ b/metadata/modules/eskimiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://dsp-media.eskimi.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:16.770Z", + "timestamp": "2026-03-02T14:45:47.201Z", "disclosures": [] } }, diff --git a/metadata/modules/etargetBidAdapter.json b/metadata/modules/etargetBidAdapter.json index 5efd286beb6..db71948ec37 100644 --- a/metadata/modules/etargetBidAdapter.json +++ b/metadata/modules/etargetBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.etarget.sk/cookies3.json": { - "timestamp": "2026-01-28T16:30:16.842Z", + "timestamp": "2026-03-02T14:45:47.226Z", "disclosures": [] } }, diff --git a/metadata/modules/euidIdSystem.json b/metadata/modules/euidIdSystem.json index 4117148b7b5..5d3d333813e 100644 --- a/metadata/modules/euidIdSystem.json +++ b/metadata/modules/euidIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ttd-misc-public-assets.s3.us-west-2.amazonaws.com/deviceStorageDisclosureURL.json": { - "timestamp": "2026-01-28T16:30:17.398Z", + "timestamp": "2026-03-02T14:45:47.806Z", "disclosures": [] } }, diff --git a/metadata/modules/exadsBidAdapter.json b/metadata/modules/exadsBidAdapter.json index 1bf45f51e78..4f78604a882 100644 --- a/metadata/modules/exadsBidAdapter.json +++ b/metadata/modules/exadsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://a.native7.com/tcf/deviceStorage.php": { - "timestamp": "2026-01-28T16:30:17.607Z", + "timestamp": "2026-03-02T14:45:48.013Z", "disclosures": [ { "identifier": "pn-zone-*", diff --git a/metadata/modules/feedadBidAdapter.json b/metadata/modules/feedadBidAdapter.json index b4bc9e17f6d..898c77b0f70 100644 --- a/metadata/modules/feedadBidAdapter.json +++ b/metadata/modules/feedadBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://api.feedad.com/tcf-device-disclosures.json": { - "timestamp": "2026-01-28T16:30:17.803Z", + "timestamp": "2026-03-02T14:45:48.194Z", "disclosures": [ { "identifier": "__fad_data", diff --git a/metadata/modules/floxisBidAdapter.json b/metadata/modules/floxisBidAdapter.json new file mode 100644 index 00000000000..c58d76bc57a --- /dev/null +++ b/metadata/modules/floxisBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "floxis", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/fwsspBidAdapter.json b/metadata/modules/fwsspBidAdapter.json index d0e9d6e3281..c950b152e00 100644 --- a/metadata/modules/fwsspBidAdapter.json +++ b/metadata/modules/fwsspBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://iab.fwmrm.net/g/devicedisclosure.json": { - "timestamp": "2026-01-28T16:30:17.913Z", + "timestamp": "2026-03-02T14:45:48.313Z", "disclosures": [] } }, diff --git a/metadata/modules/gamoshiBidAdapter.json b/metadata/modules/gamoshiBidAdapter.json index 4fdd963b192..05ce430c856 100644 --- a/metadata/modules/gamoshiBidAdapter.json +++ b/metadata/modules/gamoshiBidAdapter.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.gamoshi.com/disclosures-client-storage.json": { - "timestamp": "2026-01-28T16:30:18.136Z", - "disclosures": [] + "timestamp": "2026-03-02T14:45:48.653Z", + "disclosures": null } }, "components": [ diff --git a/metadata/modules/gemiusIdSystem.json b/metadata/modules/gemiusIdSystem.json index 6effe5fa731..9aa5b49be2d 100644 --- a/metadata/modules/gemiusIdSystem.json +++ b/metadata/modules/gemiusIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://gemius.com/media/documents/Gemius_SA_Vendor_Device_Storage.json": { - "timestamp": "2026-01-28T16:30:18.258Z", + "timestamp": "2026-03-02T14:45:49.814Z", "disclosures": [ { "identifier": "__gsyncs_gdpr", diff --git a/metadata/modules/glomexBidAdapter.json b/metadata/modules/glomexBidAdapter.json index 997f9f7bc1a..3ad4e7c7df2 100644 --- a/metadata/modules/glomexBidAdapter.json +++ b/metadata/modules/glomexBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://player.glomex.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:18.259Z", + "timestamp": "2026-03-02T14:45:49.816Z", "disclosures": [ { "identifier": "glomexUser", diff --git a/metadata/modules/goldbachBidAdapter.json b/metadata/modules/goldbachBidAdapter.json index 6b6d92bcf93..61b5f9f87a3 100644 --- a/metadata/modules/goldbachBidAdapter.json +++ b/metadata/modules/goldbachBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://gb-next.ch/TcfGoldbachDeviceStorage.json": { - "timestamp": "2026-01-28T16:30:18.282Z", + "timestamp": "2026-03-02T14:45:49.839Z", "disclosures": [ { "identifier": "dakt_2_session_id", diff --git a/metadata/modules/gridBidAdapter.json b/metadata/modules/gridBidAdapter.json index ae4df482acf..0420f51b838 100644 --- a/metadata/modules/gridBidAdapter.json +++ b/metadata/modules/gridBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.themediagrid.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:18.305Z", + "timestamp": "2026-03-02T14:45:49.864Z", "disclosures": [] } }, diff --git a/metadata/modules/gumgumBidAdapter.json b/metadata/modules/gumgumBidAdapter.json index f5735825ecb..9131fda39bc 100644 --- a/metadata/modules/gumgumBidAdapter.json +++ b/metadata/modules/gumgumBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://marketing.gumgum.com/devicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:18.450Z", + "timestamp": "2026-03-02T14:45:49.990Z", "disclosures": [] } }, diff --git a/metadata/modules/hadronIdSystem.json b/metadata/modules/hadronIdSystem.json index c0fb0c8617e..a02dd109e19 100644 --- a/metadata/modules/hadronIdSystem.json +++ b/metadata/modules/hadronIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://p.ad.gt/static/iab_tcf.json": { - "timestamp": "2026-01-28T16:30:18.502Z", + "timestamp": "2026-03-02T14:45:50.048Z", "disclosures": [ { "identifier": "au/sid", diff --git a/metadata/modules/hadronRtdProvider.json b/metadata/modules/hadronRtdProvider.json index b24598c78f8..b5eb21067e8 100644 --- a/metadata/modules/hadronRtdProvider.json +++ b/metadata/modules/hadronRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://p.ad.gt/static/iab_tcf.json": { - "timestamp": "2026-01-28T16:30:18.608Z", + "timestamp": "2026-03-02T14:45:50.186Z", "disclosures": [ { "identifier": "au/sid", diff --git a/metadata/modules/harionBidAdapter.json b/metadata/modules/harionBidAdapter.json new file mode 100644 index 00000000000..dc71450537a --- /dev/null +++ b/metadata/modules/harionBidAdapter.json @@ -0,0 +1,18 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://markappmedia.site/vendor.json": { + "timestamp": "2026-03-02T14:45:50.186Z", + "disclosures": [] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "harion", + "aliasOf": null, + "gvlid": 1406, + "disclosureURL": "https://markappmedia.site/vendor.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/holidBidAdapter.json b/metadata/modules/holidBidAdapter.json index 4342f2840f2..d5fc01d7c33 100644 --- a/metadata/modules/holidBidAdapter.json +++ b/metadata/modules/holidBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ads.holid.io/devicestorage.json": { - "timestamp": "2026-01-28T16:30:18.608Z", + "timestamp": "2026-03-02T14:45:50.576Z", "disclosures": [ { "identifier": "uids", diff --git a/metadata/modules/hybridBidAdapter.json b/metadata/modules/hybridBidAdapter.json index b812dcc3411..efc1583902c 100644 --- a/metadata/modules/hybridBidAdapter.json +++ b/metadata/modules/hybridBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://st.hybrid.ai/policy/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:18.857Z", + "timestamp": "2026-03-02T14:45:50.868Z", "disclosures": [] } }, diff --git a/metadata/modules/id5IdSystem.json b/metadata/modules/id5IdSystem.json index 822336b6feb..886832932a7 100644 --- a/metadata/modules/id5IdSystem.json +++ b/metadata/modules/id5IdSystem.json @@ -2,8 +2,250 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://id5-sync.com/tcf/disclosures.json": { - "timestamp": "2026-01-28T16:30:19.113Z", - "disclosures": [] + "timestamp": "2026-03-02T14:45:51.113Z", + "disclosures": [ + { + "identifier": "id5id", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_exp", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_last", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_last_exp", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_consent_data", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_consent_data_exp", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_pd_{partnerId}", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_pd_exp", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_pd", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_privacy", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_privacy_exp", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_{partnerId}_nb", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_{partnerId}_nb_exp", + "type": "web", + "maxAgeSeconds": 7776000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_v2_{cacheId}", + "type": "web", + "maxAgeSeconds": 1296000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_v2_signature", + "type": "web", + "maxAgeSeconds": 1296000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_extensions", + "type": "web", + "maxAgeSeconds": 28800, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_segments_{partnerId}", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5id_cached_segments_{partnerId}_exp", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5_trueLink_privacy", + "type": "web", + "maxAgeSeconds": 2592000, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-tl-ts", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-tl-redirect-timestamp", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-tl-redirect-fail", + "type": "cookie", + "maxAgeSeconds": 604800, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-tl-optout", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-true-link", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-true-link-refresh", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + }, + { + "identifier": "id5-true-link-refresh-exp", + "type": "cookie", + "maxAgeSeconds": 7776000, + "cookieRefresh": true, + "purposes": [ + 1, + 3 + ] + } + ] } }, "components": [ diff --git a/metadata/modules/identityLinkIdSystem.json b/metadata/modules/identityLinkIdSystem.json index e0da9afd224..03bcaedd660 100644 --- a/metadata/modules/identityLinkIdSystem.json +++ b/metadata/modules/identityLinkIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.ats.rlcdn.com/device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:19.391Z", + "timestamp": "2026-03-02T14:45:51.402Z", "disclosures": [ { "identifier": "_lr_retry_request", diff --git a/metadata/modules/illuminBidAdapter.json b/metadata/modules/illuminBidAdapter.json index 9872fe179fe..eadb5eea6ca 100644 --- a/metadata/modules/illuminBidAdapter.json +++ b/metadata/modules/illuminBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://admanmedia.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:19.410Z", + "timestamp": "2026-03-02T14:45:51.424Z", "disclosures": [] } }, diff --git a/metadata/modules/impactifyBidAdapter.json b/metadata/modules/impactifyBidAdapter.json index ff872bf7c59..a84d454fd03 100644 --- a/metadata/modules/impactifyBidAdapter.json +++ b/metadata/modules/impactifyBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ad.impactify.io/tcfvendors.json": { - "timestamp": "2026-01-28T16:30:19.701Z", + "timestamp": "2026-03-02T14:45:51.728Z", "disclosures": [ { "identifier": "_im*", diff --git a/metadata/modules/improvedigitalBidAdapter.json b/metadata/modules/improvedigitalBidAdapter.json index 93613334ee6..a6e1e421e03 100644 --- a/metadata/modules/improvedigitalBidAdapter.json +++ b/metadata/modules/improvedigitalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sellers.improvedigital.com/tcf-cookies.json": { - "timestamp": "2026-01-28T16:30:20.078Z", + "timestamp": "2026-03-02T14:45:52.052Z", "disclosures": [ { "identifier": "tuuid", diff --git a/metadata/modules/inmobiBidAdapter.json b/metadata/modules/inmobiBidAdapter.json index 12ac730cfab..818bc7ee34a 100644 --- a/metadata/modules/inmobiBidAdapter.json +++ b/metadata/modules/inmobiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://publisher.inmobi.com/public/disclosure": { - "timestamp": "2026-01-28T16:30:20.079Z", + "timestamp": "2026-03-02T14:45:52.052Z", "disclosures": [] } }, diff --git a/metadata/modules/insticatorBidAdapter.json b/metadata/modules/insticatorBidAdapter.json index 08318bac5bf..93ac9d8e09a 100644 --- a/metadata/modules/insticatorBidAdapter.json +++ b/metadata/modules/insticatorBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.insticator.com/iab/device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:20.115Z", + "timestamp": "2026-03-02T14:45:52.089Z", "disclosures": [ { "identifier": "visitorGeo", diff --git a/metadata/modules/insuradsBidAdapter.json b/metadata/modules/insuradsBidAdapter.json new file mode 100644 index 00000000000..05a0e236aad --- /dev/null +++ b/metadata/modules/insuradsBidAdapter.json @@ -0,0 +1,45 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://www.insurads.com/tcf-vdsod.json": { + "timestamp": "2026-03-02T14:45:52.162Z", + "disclosures": [ + { + "identifier": "___iat_ses", + "type": "cookie", + "maxAgeSeconds": 1800, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 7, + 9, + 10 + ] + }, + { + "identifier": "___iat_vis", + "type": "cookie", + "maxAgeSeconds": 15552000, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 7, + 9, + 10 + ] + } + ] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "insurads", + "aliasOf": null, + "gvlid": 596, + "disclosureURL": "https://www.insurads.com/tcf-vdsod.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/intentIqIdSystem.json b/metadata/modules/intentIqIdSystem.json index 3e419eef19a..43fe76d2cad 100644 --- a/metadata/modules/intentIqIdSystem.json +++ b/metadata/modules/intentIqIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://agent.intentiq.com/GDPR/gdpr.json": { - "timestamp": "2026-01-28T16:30:20.139Z", + "timestamp": "2026-03-02T14:45:52.351Z", "disclosures": [] } }, diff --git a/metadata/modules/invibesBidAdapter.json b/metadata/modules/invibesBidAdapter.json index 63fcebf8060..9b23ea0bc54 100644 --- a/metadata/modules/invibesBidAdapter.json +++ b/metadata/modules/invibesBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.invibes.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:20.189Z", + "timestamp": "2026-03-02T14:45:52.421Z", "disclosures": [ { "identifier": "ivvcap", diff --git a/metadata/modules/ipromBidAdapter.json b/metadata/modules/ipromBidAdapter.json index 4f8ff0b1227..7f9b4c104c2 100644 --- a/metadata/modules/ipromBidAdapter.json +++ b/metadata/modules/ipromBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://core.iprom.net/info/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:20.533Z", + "timestamp": "2026-03-02T14:45:52.785Z", "disclosures": [] } }, diff --git a/metadata/modules/ixBidAdapter.json b/metadata/modules/ixBidAdapter.json index 35f6279a5b8..ba7581331d0 100644 --- a/metadata/modules/ixBidAdapter.json +++ b/metadata/modules/ixBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.indexexchange.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:21.016Z", + "timestamp": "2026-03-02T14:45:53.259Z", "disclosures": [ { "identifier": "ix_features", diff --git a/metadata/modules/justIdSystem.json b/metadata/modules/justIdSystem.json index b83e3eb1d63..f20fbceea31 100644 --- a/metadata/modules/justIdSystem.json +++ b/metadata/modules/justIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://audience-solutions.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:21.288Z", + "timestamp": "2026-03-02T14:45:53.334Z", "disclosures": [ { "identifier": "__jtuid", diff --git a/metadata/modules/justpremiumBidAdapter.json b/metadata/modules/justpremiumBidAdapter.json index 42a09fe26b8..7fb5438d310 100644 --- a/metadata/modules/justpremiumBidAdapter.json +++ b/metadata/modules/justpremiumBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.justpremium.com/devicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:21.799Z", + "timestamp": "2026-03-02T14:45:53.863Z", "disclosures": [] } }, diff --git a/metadata/modules/jwplayerBidAdapter.json b/metadata/modules/jwplayerBidAdapter.json index c5f0094a6b1..6695015fb1e 100644 --- a/metadata/modules/jwplayerBidAdapter.json +++ b/metadata/modules/jwplayerBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.jwplayer.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:21.822Z", + "timestamp": "2026-03-02T14:45:53.882Z", "disclosures": [] } }, diff --git a/metadata/modules/kargoBidAdapter.json b/metadata/modules/kargoBidAdapter.json index 96032f6827e..18c7713446a 100644 --- a/metadata/modules/kargoBidAdapter.json +++ b/metadata/modules/kargoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://storage.cloud.kargo.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:21.990Z", + "timestamp": "2026-03-02T14:45:54.165Z", "disclosures": [ { "identifier": "krg_crb", diff --git a/metadata/modules/kueezRtbBidAdapter.json b/metadata/modules/kueezRtbBidAdapter.json index 65251cb83cd..38316d32257 100644 --- a/metadata/modules/kueezRtbBidAdapter.json +++ b/metadata/modules/kueezRtbBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://en.kueez.com/tcf.json": { - "timestamp": "2026-01-28T16:30:22.016Z", + "timestamp": "2026-03-02T14:45:54.193Z", "disclosures": [ { "identifier": "ck48wz12sqj7", diff --git a/metadata/modules/leagueMBidAdapter.json b/metadata/modules/leagueMBidAdapter.json new file mode 100644 index 00000000000..f4b02875bbb --- /dev/null +++ b/metadata/modules/leagueMBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "leagueM", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/limelightDigitalBidAdapter.json b/metadata/modules/limelightDigitalBidAdapter.json index 32782e737c0..14e44dfc1e0 100644 --- a/metadata/modules/limelightDigitalBidAdapter.json +++ b/metadata/modules/limelightDigitalBidAdapter.json @@ -2,11 +2,11 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://policy.iion.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:22.072Z", + "timestamp": "2026-03-02T14:45:54.240Z", "disclosures": [] }, "https://orangeclickmedia.com/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:22.103Z", + "timestamp": "2026-03-02T14:45:54.278Z", "disclosures": [] } }, @@ -32,13 +32,6 @@ "gvlid": 1358, "disclosureURL": "https://policy.iion.io/deviceStorage.json" }, - { - "componentType": "bidder", - "componentName": "apester", - "aliasOf": "limelightDigital", - "gvlid": null, - "disclosureURL": null - }, { "componentType": "bidder", "componentName": "adsyield", @@ -102,13 +95,6 @@ "gvlid": null, "disclosureURL": null }, - { - "componentType": "bidder", - "componentName": "adnimation", - "aliasOf": "limelightDigital", - "gvlid": null, - "disclosureURL": null - }, { "componentType": "bidder", "componentName": "rtbdemand", diff --git a/metadata/modules/liveIntentIdSystem.json b/metadata/modules/liveIntentIdSystem.json index 1cb74699212..73069893950 100644 --- a/metadata/modules/liveIntentIdSystem.json +++ b/metadata/modules/liveIntentIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://b-code.liadm.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:22.104Z", + "timestamp": "2026-03-02T14:45:54.278Z", "disclosures": [ { "identifier": "_lc2_fpi", diff --git a/metadata/modules/liveIntentRtdProvider.json b/metadata/modules/liveIntentRtdProvider.json index c7ec883ac04..8c36b5b69d2 100644 --- a/metadata/modules/liveIntentRtdProvider.json +++ b/metadata/modules/liveIntentRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://b-code.liadm.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:22.118Z", + "timestamp": "2026-03-02T14:45:54.418Z", "disclosures": [ { "identifier": "_lc2_fpi", diff --git a/metadata/modules/livewrappedBidAdapter.json b/metadata/modules/livewrappedBidAdapter.json index 03011a99e3a..a5fb8083be9 100644 --- a/metadata/modules/livewrappedBidAdapter.json +++ b/metadata/modules/livewrappedBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://content.lwadm.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:22.119Z", + "timestamp": "2026-03-02T14:45:54.419Z", "disclosures": [ { "identifier": "uid", diff --git a/metadata/modules/locIdSystem.json b/metadata/modules/locIdSystem.json new file mode 100644 index 00000000000..87e8fc03475 --- /dev/null +++ b/metadata/modules/locIdSystem.json @@ -0,0 +1,20 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "userId", + "componentName": "locId", + "gvlid": null, + "disclosureURL": null, + "aliasOf": null + }, + { + "componentType": "userId", + "componentName": "locid", + "gvlid": null, + "disclosureURL": null, + "aliasOf": "locId" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/loopmeBidAdapter.json b/metadata/modules/loopmeBidAdapter.json index 57dbea94060..33632aaca12 100644 --- a/metadata/modules/loopmeBidAdapter.json +++ b/metadata/modules/loopmeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://co.loopme.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:22.147Z", + "timestamp": "2026-03-02T14:45:54.453Z", "disclosures": [] } }, diff --git a/metadata/modules/lotamePanoramaIdSystem.json b/metadata/modules/lotamePanoramaIdSystem.json index 7bf465e8b28..1a84524e9d6 100644 --- a/metadata/modules/lotamePanoramaIdSystem.json +++ b/metadata/modules/lotamePanoramaIdSystem.json @@ -2,8 +2,65 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tags.crwdcntrl.net/privacy/tcf-purposes.json": { - "timestamp": "2026-01-28T16:30:22.264Z", + "timestamp": "2026-03-02T14:45:54.576Z", "disclosures": [ + { + "identifier": "_cc_id", + "type": "cookie", + "maxAgeSeconds": 23328000, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] + }, + { + "identifier": "_cc_cc", + "type": "cookie", + "maxAgeSeconds": 23328000, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] + }, + { + "identifier": "_cc_aud", + "type": "cookie", + "maxAgeSeconds": 23328000, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] + }, { "identifier": "lotame_domain_check", "type": "cookie", @@ -23,6 +80,25 @@ 11 ] }, + { + "identifier": "_pubcid", + "type": "cookie", + "maxAgeSeconds": 23328000, + "cookieRefresh": true, + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] + }, { "identifier": "panoramaId", "type": "web", @@ -124,6 +200,23 @@ 10, 11 ] + }, + { + "identifier": "_pubcid", + "type": "web", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ] } ] } diff --git a/metadata/modules/luponmediaBidAdapter.json b/metadata/modules/luponmediaBidAdapter.json index 55ff987e50a..96e987d9dc2 100644 --- a/metadata/modules/luponmediaBidAdapter.json +++ b/metadata/modules/luponmediaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://luponmedia.com/vendor_device_storage.json": { - "timestamp": "2026-01-28T16:30:22.285Z", + "timestamp": "2026-03-02T14:45:54.640Z", "disclosures": [] } }, diff --git a/metadata/modules/madvertiseBidAdapter.json b/metadata/modules/madvertiseBidAdapter.json index 0e9003e97bb..096ca78f06b 100644 --- a/metadata/modules/madvertiseBidAdapter.json +++ b/metadata/modules/madvertiseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adserver.bluestack.app/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:22.706Z", + "timestamp": "2026-03-02T14:45:55.051Z", "disclosures": [] } }, diff --git a/metadata/modules/marsmediaBidAdapter.json b/metadata/modules/marsmediaBidAdapter.json index dcaaeb86fce..e20881844c8 100644 --- a/metadata/modules/marsmediaBidAdapter.json +++ b/metadata/modules/marsmediaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://mars.media/apis/tcf-v2.json": { - "timestamp": "2026-01-28T16:30:23.103Z", + "timestamp": "2026-03-02T14:45:55.409Z", "disclosures": [] } }, diff --git a/metadata/modules/mediaConsortiumBidAdapter.json b/metadata/modules/mediaConsortiumBidAdapter.json index 066fa719827..19b9a989b2c 100644 --- a/metadata/modules/mediaConsortiumBidAdapter.json +++ b/metadata/modules/mediaConsortiumBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.hubvisor.io/assets/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:23.277Z", + "timestamp": "2026-03-02T14:45:55.518Z", "disclosures": [ { "identifier": "hbv:turbo-cmp", diff --git a/metadata/modules/mediaforceBidAdapter.json b/metadata/modules/mediaforceBidAdapter.json index 8d3aa85d0cb..43aee7b5d99 100644 --- a/metadata/modules/mediaforceBidAdapter.json +++ b/metadata/modules/mediaforceBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://comparisons.org/privacy.json": { - "timestamp": "2026-01-28T16:30:23.420Z", + "timestamp": "2026-03-02T14:45:55.650Z", "disclosures": [] } }, diff --git a/metadata/modules/mediafuseBidAdapter.json b/metadata/modules/mediafuseBidAdapter.json index 26645889fa4..64dfcf767a5 100644 --- a/metadata/modules/mediafuseBidAdapter.json +++ b/metadata/modules/mediafuseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://acdn.adnxs.com/gvl/1d/xandrdevicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:23.465Z", + "timestamp": "2026-03-02T14:45:55.669Z", "disclosures": [] } }, diff --git a/metadata/modules/mediagoBidAdapter.json b/metadata/modules/mediagoBidAdapter.json index a270ee3d116..ffa894357ad 100644 --- a/metadata/modules/mediagoBidAdapter.json +++ b/metadata/modules/mediagoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.mediago.io/js/tcf.json": { - "timestamp": "2026-01-28T16:30:23.466Z", + "timestamp": "2026-03-02T14:45:55.670Z", "disclosures": [] } }, diff --git a/metadata/modules/mediakeysBidAdapter.json b/metadata/modules/mediakeysBidAdapter.json index f240f43bcc6..c41604e62be 100644 --- a/metadata/modules/mediakeysBidAdapter.json +++ b/metadata/modules/mediakeysBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s3.eu-west-3.amazonaws.com/adserving.resourcekeys.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:23.528Z", + "timestamp": "2026-03-02T14:45:55.769Z", "disclosures": [] } }, diff --git a/metadata/modules/medianetBidAdapter.json b/metadata/modules/medianetBidAdapter.json index 60aeed6e7e0..b62853ac937 100644 --- a/metadata/modules/medianetBidAdapter.json +++ b/metadata/modules/medianetBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.media.net/tcfv2/gvl/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:23.849Z", + "timestamp": "2026-03-02T14:45:56.051Z", "disclosures": [ { "identifier": "_mNExInsl", @@ -246,7 +246,7 @@ ] }, "https://trustedstack.com/tcf/gvl/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:23.898Z", + "timestamp": "2026-03-02T14:45:56.188Z", "disclosures": [ { "identifier": "usp_status", diff --git a/metadata/modules/mediasquareBidAdapter.json b/metadata/modules/mediasquareBidAdapter.json index d3f0d0f1e80..b3c225207bc 100644 --- a/metadata/modules/mediasquareBidAdapter.json +++ b/metadata/modules/mediasquareBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://mediasquare.fr/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:23.940Z", + "timestamp": "2026-03-02T14:45:56.239Z", "disclosures": [] } }, diff --git a/metadata/modules/mgidBidAdapter.json b/metadata/modules/mgidBidAdapter.json index 6de647d3359..d6da81c2fe5 100644 --- a/metadata/modules/mgidBidAdapter.json +++ b/metadata/modules/mgidBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.mgid.com/assets/devicestorage.json": { - "timestamp": "2026-01-28T16:30:24.472Z", + "timestamp": "2026-03-02T14:45:56.794Z", "disclosures": [] } }, diff --git a/metadata/modules/mgidRtdProvider.json b/metadata/modules/mgidRtdProvider.json index c59d0acffd1..d6dd6937212 100644 --- a/metadata/modules/mgidRtdProvider.json +++ b/metadata/modules/mgidRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.mgid.com/assets/devicestorage.json": { - "timestamp": "2026-01-28T16:30:24.565Z", + "timestamp": "2026-03-02T14:45:56.864Z", "disclosures": [] } }, diff --git a/metadata/modules/mgidXBidAdapter.json b/metadata/modules/mgidXBidAdapter.json index 3f4ae1d1507..d0da32736ce 100644 --- a/metadata/modules/mgidXBidAdapter.json +++ b/metadata/modules/mgidXBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.mgid.com/assets/devicestorage.json": { - "timestamp": "2026-01-28T16:30:24.565Z", + "timestamp": "2026-03-02T14:45:56.864Z", "disclosures": [] } }, diff --git a/metadata/modules/mileBidAdapter.json b/metadata/modules/mileBidAdapter.json new file mode 100644 index 00000000000..ba3e8b683fc --- /dev/null +++ b/metadata/modules/mileBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "mile", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/minutemediaBidAdapter.json b/metadata/modules/minutemediaBidAdapter.json index 33d4ba2e97e..9908f3b78ee 100644 --- a/metadata/modules/minutemediaBidAdapter.json +++ b/metadata/modules/minutemediaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://disclosures.mmctsvc.com/device-storage.json": { - "timestamp": "2026-01-28T16:30:24.567Z", + "timestamp": "2026-03-02T14:45:56.865Z", "disclosures": [] } }, diff --git a/metadata/modules/missenaBidAdapter.json b/metadata/modules/missenaBidAdapter.json index 721444fc081..14a16812ce4 100644 --- a/metadata/modules/missenaBidAdapter.json +++ b/metadata/modules/missenaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ad.missena.io/iab.json": { - "timestamp": "2026-01-28T16:30:24.587Z", + "timestamp": "2026-03-02T14:45:56.886Z", "disclosures": [] } }, diff --git a/metadata/modules/mobianRtdProvider.json b/metadata/modules/mobianRtdProvider.json index 4c8248d6f80..1ce8457b058 100644 --- a/metadata/modules/mobianRtdProvider.json +++ b/metadata/modules/mobianRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://js.outcomes.net/tcf.json": { - "timestamp": "2026-01-28T16:30:24.642Z", + "timestamp": "2026-03-02T14:45:56.944Z", "disclosures": [] } }, diff --git a/metadata/modules/mobkoiBidAdapter.json b/metadata/modules/mobkoiBidAdapter.json index 2aaa9ba6fbe..3982ab341b1 100644 --- a/metadata/modules/mobkoiBidAdapter.json +++ b/metadata/modules/mobkoiBidAdapter.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.maximus.mobkoi.com/tcf/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:24.662Z", - "disclosures": [] + "timestamp": "2026-03-02T14:45:57.043Z", + "disclosures": null } }, "components": [ diff --git a/metadata/modules/mobkoiIdSystem.json b/metadata/modules/mobkoiIdSystem.json index a64f5821912..8f9ed0091ef 100644 --- a/metadata/modules/mobkoiIdSystem.json +++ b/metadata/modules/mobkoiIdSystem.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.maximus.mobkoi.com/tcf/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:24.690Z", - "disclosures": [] + "timestamp": "2026-03-02T14:45:57.065Z", + "disclosures": null } }, "components": [ diff --git a/metadata/modules/msftBidAdapter.json b/metadata/modules/msftBidAdapter.json index 397bbfb971d..8ac1b408eae 100644 --- a/metadata/modules/msftBidAdapter.json +++ b/metadata/modules/msftBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://acdn.adnxs.com/gvl/1d/xandrdevicestoragedisclosures.json": { - "timestamp": "2026-01-28T16:30:24.691Z", + "timestamp": "2026-03-02T14:45:57.066Z", "disclosures": [] } }, diff --git a/metadata/modules/nativeryBidAdapter.json b/metadata/modules/nativeryBidAdapter.json index b2716873663..2a3f0c5c99a 100644 --- a/metadata/modules/nativeryBidAdapter.json +++ b/metadata/modules/nativeryBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdnimg.nativery.com/widget/js/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:24.694Z", + "timestamp": "2026-03-02T14:45:57.067Z", "disclosures": [] } }, diff --git a/metadata/modules/nativoBidAdapter.json b/metadata/modules/nativoBidAdapter.json index 2edcc2b20c9..59662e64c8a 100644 --- a/metadata/modules/nativoBidAdapter.json +++ b/metadata/modules/nativoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://iab.nativo.com/tcf-disclosures.json": { - "timestamp": "2026-01-28T16:30:25.034Z", + "timestamp": "2026-03-02T14:45:57.381Z", "disclosures": [] } }, diff --git a/metadata/modules/newspassidBidAdapter.json b/metadata/modules/newspassidBidAdapter.json index 2bdde04b806..57fd3223351 100644 --- a/metadata/modules/newspassidBidAdapter.json +++ b/metadata/modules/newspassidBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.aditude.com/storageaccess.json": { - "timestamp": "2026-01-28T16:30:25.072Z", + "timestamp": "2026-03-02T14:45:57.429Z", "disclosures": [] } }, diff --git a/metadata/modules/nextMillenniumBidAdapter.json b/metadata/modules/nextMillenniumBidAdapter.json index 4a1acbcebee..d57a7a52695 100644 --- a/metadata/modules/nextMillenniumBidAdapter.json +++ b/metadata/modules/nextMillenniumBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://nextmillennium.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:25.073Z", + "timestamp": "2026-03-02T14:45:57.430Z", "disclosures": [] } }, diff --git a/metadata/modules/nextrollBidAdapter.json b/metadata/modules/nextrollBidAdapter.json index 3235d22633f..f366a7a8120 100644 --- a/metadata/modules/nextrollBidAdapter.json +++ b/metadata/modules/nextrollBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s.adroll.com/shares/device_storage.json": { - "timestamp": "2026-01-28T16:30:25.140Z", + "timestamp": "2026-03-02T14:45:57.516Z", "disclosures": [ { "identifier": "__adroll_fpc", diff --git a/metadata/modules/nexx360BidAdapter.json b/metadata/modules/nexx360BidAdapter.json index 8c05a5de13c..00c1ef09267 100644 --- a/metadata/modules/nexx360BidAdapter.json +++ b/metadata/modules/nexx360BidAdapter.json @@ -2,19 +2,19 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://fast.nexx360.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:26.058Z", + "timestamp": "2026-03-02T14:45:58.404Z", "disclosures": [] }, "https://static.first-id.fr/tcf/cookie.json": { - "timestamp": "2026-01-28T16:30:25.421Z", + "timestamp": "2026-03-02T14:45:57.804Z", "disclosures": [] }, "https://i.plug.it/banners/js/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:25.445Z", + "timestamp": "2026-03-02T14:45:57.826Z", "disclosures": [] }, "https://player.glomex.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:25.665Z", + "timestamp": "2026-03-02T14:45:57.949Z", "disclosures": [ { "identifier": "glomexUser", @@ -46,7 +46,7 @@ ] }, "https://gdpr.pubx.ai/devicestoragedisclosure.json": { - "timestamp": "2026-01-28T16:30:25.665Z", + "timestamp": "2026-03-02T14:45:57.949Z", "disclosures": [ { "identifier": "pubx:defaults", @@ -61,7 +61,7 @@ ] }, "https://yieldbird.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:25.684Z", + "timestamp": "2026-03-02T14:45:58.021Z", "disclosures": [] } }, diff --git a/metadata/modules/nobidBidAdapter.json b/metadata/modules/nobidBidAdapter.json index e87c1602d61..056f7d06193 100644 --- a/metadata/modules/nobidBidAdapter.json +++ b/metadata/modules/nobidBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://public.servenobid.com/gdpr_tcf/vendor_device_storage_operational_disclosures.json": { - "timestamp": "2026-01-28T16:30:26.059Z", + "timestamp": "2026-03-02T14:45:58.405Z", "disclosures": [] } }, diff --git a/metadata/modules/nodalsAiRtdProvider.json b/metadata/modules/nodalsAiRtdProvider.json index 63188ce57d5..3c0a03590fe 100644 --- a/metadata/modules/nodalsAiRtdProvider.json +++ b/metadata/modules/nodalsAiRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static.nodals.ai/vendor.json": { - "timestamp": "2026-01-28T16:30:26.074Z", + "timestamp": "2026-03-02T14:45:58.420Z", "disclosures": [ { "identifier": "localStorage", diff --git a/metadata/modules/novatiqIdSystem.json b/metadata/modules/novatiqIdSystem.json index 1191fd80de1..704ad832740 100644 --- a/metadata/modules/novatiqIdSystem.json +++ b/metadata/modules/novatiqIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://novatiq.com/privacy/iab/novatiq.json": { - "timestamp": "2026-01-28T16:30:27.691Z", + "timestamp": "2026-03-02T14:46:00.252Z", "disclosures": [ { "identifier": "novatiq", diff --git a/metadata/modules/oguryBidAdapter.json b/metadata/modules/oguryBidAdapter.json index 3b044f32034..e0eda9c248a 100644 --- a/metadata/modules/oguryBidAdapter.json +++ b/metadata/modules/oguryBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://privacy.ogury.co/disclosure.json": { - "timestamp": "2026-01-28T16:30:28.031Z", + "timestamp": "2026-03-02T14:46:00.621Z", "disclosures": [] } }, diff --git a/metadata/modules/omnidexBidAdapter.json b/metadata/modules/omnidexBidAdapter.json index cb9afb31fb1..b9cfde98549 100644 --- a/metadata/modules/omnidexBidAdapter.json +++ b/metadata/modules/omnidexBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.omni-dex.io/devicestorage.json": { - "timestamp": "2026-01-28T16:30:28.095Z", + "timestamp": "2026-03-02T14:46:00.670Z", "disclosures": [ { "identifier": "ck48wz12sqj7", diff --git a/metadata/modules/omsBidAdapter.json b/metadata/modules/omsBidAdapter.json index e0f6d4fa074..bf3d6e763b9 100644 --- a/metadata/modules/omsBidAdapter.json +++ b/metadata/modules/omsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.marphezis.com/tcf-vendor-disclosures.json": { - "timestamp": "2026-01-28T16:30:28.157Z", + "timestamp": "2026-03-02T14:46:00.723Z", "disclosures": [] } }, diff --git a/metadata/modules/onetagBidAdapter.json b/metadata/modules/onetagBidAdapter.json index 3d0c4ca8dee..94e1cbede34 100644 --- a/metadata/modules/onetagBidAdapter.json +++ b/metadata/modules/onetagBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://onetag-cdn.com/privacy/tcf_storage.json": { - "timestamp": "2026-01-28T16:30:28.158Z", + "timestamp": "2026-03-02T14:46:00.724Z", "disclosures": [ { "identifier": "onetag_sid", diff --git a/metadata/modules/openwebBidAdapter.json b/metadata/modules/openwebBidAdapter.json index e84a0376dac..b4ee396237c 100644 --- a/metadata/modules/openwebBidAdapter.json +++ b/metadata/modules/openwebBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://spotim-prd-static-assets.s3.amazonaws.com/iab/device-storage.json": { - "timestamp": "2026-01-28T16:30:28.487Z", + "timestamp": "2026-03-02T14:46:01.014Z", "disclosures": [] } }, diff --git a/metadata/modules/openxBidAdapter.json b/metadata/modules/openxBidAdapter.json index 6d6fa2c2c23..dfb10023709 100644 --- a/metadata/modules/openxBidAdapter.json +++ b/metadata/modules/openxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.openx.com/device-storage.json": { - "timestamp": "2026-01-28T16:30:28.525Z", + "timestamp": "2026-03-02T14:46:01.052Z", "disclosures": [] } }, diff --git a/metadata/modules/operaadsBidAdapter.json b/metadata/modules/operaadsBidAdapter.json index 76226db2c54..be92865dfd2 100644 --- a/metadata/modules/operaadsBidAdapter.json +++ b/metadata/modules/operaadsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://res.adx.opera.com/dsd.json": { - "timestamp": "2026-01-28T16:30:28.576Z", + "timestamp": "2026-03-02T14:46:01.082Z", "disclosures": [] } }, diff --git a/metadata/modules/optidigitalBidAdapter.json b/metadata/modules/optidigitalBidAdapter.json index 1e17c7686fd..51ed301458d 100644 --- a/metadata/modules/optidigitalBidAdapter.json +++ b/metadata/modules/optidigitalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://scripts.opti-digital.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:28.625Z", + "timestamp": "2026-03-02T14:46:01.269Z", "disclosures": [] } }, diff --git a/metadata/modules/optoutBidAdapter.json b/metadata/modules/optoutBidAdapter.json index a894055a0b3..fef02111513 100644 --- a/metadata/modules/optoutBidAdapter.json +++ b/metadata/modules/optoutBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://adserving.optoutadvertising.com/dsd": { - "timestamp": "2026-01-28T16:30:28.705Z", + "timestamp": "2026-03-02T14:46:01.427Z", "disclosures": [] } }, diff --git a/metadata/modules/orbidderBidAdapter.json b/metadata/modules/orbidderBidAdapter.json index 0ae9bf725ab..b9571894c8a 100644 --- a/metadata/modules/orbidderBidAdapter.json +++ b/metadata/modules/orbidderBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://orbidder.otto.de/disclosure/dsd.json": { - "timestamp": "2026-01-28T16:30:28.971Z", + "timestamp": "2026-03-02T14:46:01.687Z", "disclosures": [] } }, diff --git a/metadata/modules/outbrainBidAdapter.json b/metadata/modules/outbrainBidAdapter.json index 5e5a4cd4aeb..325c70c587c 100644 --- a/metadata/modules/outbrainBidAdapter.json +++ b/metadata/modules/outbrainBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.outbrain.com/privacy/wp-json/privacy/v2/devicestorage.json": { - "timestamp": "2026-01-28T16:30:29.295Z", + "timestamp": "2026-03-02T14:46:02.006Z", "disclosures": [ { "identifier": "dicbo_id", diff --git a/metadata/modules/ozoneBidAdapter.json b/metadata/modules/ozoneBidAdapter.json index ea70878496b..23d5ad8eb09 100644 --- a/metadata/modules/ozoneBidAdapter.json +++ b/metadata/modules/ozoneBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://prebid.the-ozone-project.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:29.606Z", + "timestamp": "2026-03-02T14:46:02.249Z", "disclosures": [] } }, diff --git a/metadata/modules/pairIdSystem.json b/metadata/modules/pairIdSystem.json index d83173c0933..d4c804fcc8c 100644 --- a/metadata/modules/pairIdSystem.json +++ b/metadata/modules/pairIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.gstatic.com/iabtcf/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:29.871Z", + "timestamp": "2026-03-02T14:46:02.471Z", "disclosures": [ { "identifier": "__gads", diff --git a/metadata/modules/panxoBidAdapter.json b/metadata/modules/panxoBidAdapter.json index 271639b6bcc..e06de639217 100644 --- a/metadata/modules/panxoBidAdapter.json +++ b/metadata/modules/panxoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.panxo.ai/tcf/device-storage.json": { - "timestamp": "2026-01-28T16:30:29.889Z", + "timestamp": "2026-03-02T14:46:02.495Z", "disclosures": [ { "identifier": "panxo_uid", diff --git a/metadata/modules/panxoRtdProvider.json b/metadata/modules/panxoRtdProvider.json new file mode 100644 index 00000000000..5ad682b104d --- /dev/null +++ b/metadata/modules/panxoRtdProvider.json @@ -0,0 +1,12 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "rtd", + "componentName": "panxo", + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/performaxBidAdapter.json b/metadata/modules/performaxBidAdapter.json index f845d868039..5bdea8a1dd9 100644 --- a/metadata/modules/performaxBidAdapter.json +++ b/metadata/modules/performaxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.performax.cz/device_storage.json": { - "timestamp": "2026-01-28T16:30:30.114Z", + "timestamp": "2026-03-02T14:46:02.691Z", "disclosures": [ { "identifier": "px2uid", diff --git a/metadata/modules/permutiveIdentityManagerIdSystem.json b/metadata/modules/permutiveIdentityManagerIdSystem.json index 8d762cfa8ac..647b813dccd 100644 --- a/metadata/modules/permutiveIdentityManagerIdSystem.json +++ b/metadata/modules/permutiveIdentityManagerIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.permutive.app/tcf/tcf.json": { - "timestamp": "2026-01-28T16:30:30.530Z", + "timestamp": "2026-03-02T14:46:03.107Z", "disclosures": [ { "identifier": "_pdfps", diff --git a/metadata/modules/permutiveRtdProvider.json b/metadata/modules/permutiveRtdProvider.json index b3183046ced..0f41067e138 100644 --- a/metadata/modules/permutiveRtdProvider.json +++ b/metadata/modules/permutiveRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.permutive.app/tcf/tcf.json": { - "timestamp": "2026-01-28T16:30:30.723Z", + "timestamp": "2026-03-02T14:46:03.283Z", "disclosures": [ { "identifier": "_pdfps", diff --git a/metadata/modules/pixfutureBidAdapter.json b/metadata/modules/pixfutureBidAdapter.json index 404e5160044..c04bfe3f164 100644 --- a/metadata/modules/pixfutureBidAdapter.json +++ b/metadata/modules/pixfutureBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.pixfuture.com/vendor-disclosures.json": { - "timestamp": "2026-01-28T16:30:30.724Z", + "timestamp": "2026-03-02T14:46:03.285Z", "disclosures": [] } }, diff --git a/metadata/modules/playdigoBidAdapter.json b/metadata/modules/playdigoBidAdapter.json index e1cfc53a2be..56ff6f0ebc5 100644 --- a/metadata/modules/playdigoBidAdapter.json +++ b/metadata/modules/playdigoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://playdigo.com/file.json": { - "timestamp": "2026-01-28T16:30:30.771Z", + "timestamp": "2026-03-02T14:46:03.345Z", "disclosures": [] } }, diff --git a/metadata/modules/prebid-core.json b/metadata/modules/prebid-core.json index 27215922c30..3ef5aaa70c7 100644 --- a/metadata/modules/prebid-core.json +++ b/metadata/modules/prebid-core.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/probes.json": { - "timestamp": "2026-01-28T16:29:58.199Z", + "timestamp": "2026-03-02T14:44:46.315Z", "disclosures": [ { "identifier": "_rdc*", @@ -23,7 +23,7 @@ ] }, "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/debugging.json": { - "timestamp": "2026-01-28T16:29:58.213Z", + "timestamp": "2026-03-02T14:44:46.315Z", "disclosures": [ { "identifier": "__*_debugging__", @@ -41,6 +41,11 @@ "componentName": "fpdEnrichment", "disclosureURL": "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/probes.json" }, + { + "componentType": "prebid", + "componentName": "storage", + "disclosureURL": "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/probes.json" + }, { "componentType": "prebid", "componentName": "debugging", diff --git a/metadata/modules/precisoBidAdapter.json b/metadata/modules/precisoBidAdapter.json index 051accb3c62..63ae55fec56 100644 --- a/metadata/modules/precisoBidAdapter.json +++ b/metadata/modules/precisoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://preciso.net/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:30.948Z", + "timestamp": "2026-03-02T14:46:03.527Z", "disclosures": [ { "identifier": "XXXXX_viewnew", diff --git a/metadata/modules/prismaBidAdapter.json b/metadata/modules/prismaBidAdapter.json index 0d1691488d9..b1668166cfa 100644 --- a/metadata/modules/prismaBidAdapter.json +++ b/metadata/modules/prismaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://fast.nexx360.io/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:30.998Z", + "timestamp": "2026-03-02T14:46:03.818Z", "disclosures": [] } }, diff --git a/metadata/modules/programmaticXBidAdapter.json b/metadata/modules/programmaticXBidAdapter.json index 1221f3c8eb4..e88a5f370ba 100644 --- a/metadata/modules/programmaticXBidAdapter.json +++ b/metadata/modules/programmaticXBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://progrtb.com/tcf-vendor-disclosures.json": { - "timestamp": "2026-01-28T16:30:30.998Z", + "timestamp": "2026-03-02T14:46:03.818Z", "disclosures": [] } }, diff --git a/metadata/modules/proxistoreBidAdapter.json b/metadata/modules/proxistoreBidAdapter.json index f6bd76fdd1b..905a96a3b49 100644 --- a/metadata/modules/proxistoreBidAdapter.json +++ b/metadata/modules/proxistoreBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://abs.proxistore.com/assets/json/proxistore_device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:31.059Z", + "timestamp": "2026-03-02T14:46:03.882Z", "disclosures": [] } }, diff --git a/metadata/modules/publinkIdSystem.json b/metadata/modules/publinkIdSystem.json index fb02ded585d..7ad66a8914c 100644 --- a/metadata/modules/publinkIdSystem.json +++ b/metadata/modules/publinkIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s-usweb.dotomi.com/assets/js/taggy-js/2.18.9/device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:31.543Z", + "timestamp": "2026-03-02T14:46:04.343Z", "disclosures": [ { "identifier": "dtm_status", diff --git a/metadata/modules/pubmaticBidAdapter.json b/metadata/modules/pubmaticBidAdapter.json index 607009f53ac..7dc64f1d033 100644 --- a/metadata/modules/pubmaticBidAdapter.json +++ b/metadata/modules/pubmaticBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.pubmatic.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:31.544Z", + "timestamp": "2026-03-02T14:46:04.343Z", "disclosures": [] } }, diff --git a/metadata/modules/pubmaticIdSystem.json b/metadata/modules/pubmaticIdSystem.json index c57d7c0d7c4..2545e56212f 100644 --- a/metadata/modules/pubmaticIdSystem.json +++ b/metadata/modules/pubmaticIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.pubmatic.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:31.576Z", + "timestamp": "2026-03-02T14:46:04.569Z", "disclosures": [] } }, diff --git a/metadata/modules/pubstackBidAdapter.json b/metadata/modules/pubstackBidAdapter.json new file mode 100644 index 00000000000..5081e22a00d --- /dev/null +++ b/metadata/modules/pubstackBidAdapter.json @@ -0,0 +1,25 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://cdn.pbstck.com/privacy_policies/device_storage_disclosures.json": { + "timestamp": "2026-03-02T14:46:04.602Z", + "disclosures": [] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "pubstack", + "aliasOf": null, + "gvlid": 1408, + "disclosureURL": "https://cdn.pbstck.com/privacy_policies/device_storage_disclosures.json" + }, + { + "componentType": "bidder", + "componentName": "pubstack_server", + "aliasOf": "pubstack", + "gvlid": 1408, + "disclosureURL": "https://cdn.pbstck.com/privacy_policies/device_storage_disclosures.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/pulsepointBidAdapter.json b/metadata/modules/pulsepointBidAdapter.json index 4bacd53227a..3134a58466f 100644 --- a/metadata/modules/pulsepointBidAdapter.json +++ b/metadata/modules/pulsepointBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bh.contextweb.com/tcf/vendorInfo.json": { - "timestamp": "2026-01-28T16:30:31.577Z", + "timestamp": "2026-03-02T14:46:04.603Z", "disclosures": [] } }, diff --git a/metadata/modules/quantcastBidAdapter.json b/metadata/modules/quantcastBidAdapter.json index 426abc3ac5c..0b8de794a6c 100644 --- a/metadata/modules/quantcastBidAdapter.json +++ b/metadata/modules/quantcastBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.quantcast.com/.well-known/devicestorage.json": { - "timestamp": "2026-01-28T16:30:31.593Z", + "timestamp": "2026-03-02T14:46:04.619Z", "disclosures": [ { "identifier": "__qca", diff --git a/metadata/modules/quantcastIdSystem.json b/metadata/modules/quantcastIdSystem.json index 6c28e90ab63..0ac7d60db4a 100644 --- a/metadata/modules/quantcastIdSystem.json +++ b/metadata/modules/quantcastIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.quantcast.com/.well-known/devicestorage.json": { - "timestamp": "2026-01-28T16:30:31.773Z", + "timestamp": "2026-03-02T14:46:04.798Z", "disclosures": [ { "identifier": "__qca", diff --git a/metadata/modules/r2b2BidAdapter.json b/metadata/modules/r2b2BidAdapter.json index 6b3f923e892..673069e3845 100644 --- a/metadata/modules/r2b2BidAdapter.json +++ b/metadata/modules/r2b2BidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://delivery.r2b2.io/cookie_disclosure": { - "timestamp": "2026-01-28T16:30:31.773Z", + "timestamp": "2026-03-02T14:46:04.800Z", "disclosures": [ { "identifier": "AdTrack-hide-*", diff --git a/metadata/modules/readpeakBidAdapter.json b/metadata/modules/readpeakBidAdapter.json index 6b75cbc9276..752bc1a2f76 100644 --- a/metadata/modules/readpeakBidAdapter.json +++ b/metadata/modules/readpeakBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static.readpeak.com/tcf/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:32.145Z", + "timestamp": "2026-03-02T14:46:05.271Z", "disclosures": [ { "identifier": "rp_uidfp", diff --git a/metadata/modules/relayBidAdapter.json b/metadata/modules/relayBidAdapter.json index fe416c67d88..622cc457012 100644 --- a/metadata/modules/relayBidAdapter.json +++ b/metadata/modules/relayBidAdapter.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://relay42.com/hubfs/raw_assets/public/IAB.json": { - "timestamp": "2026-01-28T16:30:32.167Z", - "disclosures": [] + "timestamp": "2026-03-02T14:46:05.294Z", + "disclosures": null } }, "components": [ diff --git a/metadata/modules/relevantdigitalBidAdapter.json b/metadata/modules/relevantdigitalBidAdapter.json index 08eedf926e5..5addfe8ad58 100644 --- a/metadata/modules/relevantdigitalBidAdapter.json +++ b/metadata/modules/relevantdigitalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.relevant-digital.com/resources/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:32.375Z", + "timestamp": "2026-03-02T14:46:06.100Z", "disclosures": [] } }, diff --git a/metadata/modules/resetdigitalBidAdapter.json b/metadata/modules/resetdigitalBidAdapter.json index 703482de16d..dd359941cee 100644 --- a/metadata/modules/resetdigitalBidAdapter.json +++ b/metadata/modules/resetdigitalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://resetdigital.co/GDPR-TCF.json": { - "timestamp": "2026-01-28T16:30:32.683Z", + "timestamp": "2026-03-02T14:46:06.261Z", "disclosures": [] } }, diff --git a/metadata/modules/responsiveAdsBidAdapter.json b/metadata/modules/responsiveAdsBidAdapter.json index 89d23bb6652..37dc05e23e9 100644 --- a/metadata/modules/responsiveAdsBidAdapter.json +++ b/metadata/modules/responsiveAdsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://publish.responsiveads.com/tcf/tcf-v2.json": { - "timestamp": "2026-01-28T16:30:32.722Z", + "timestamp": "2026-03-02T14:46:06.304Z", "disclosures": [] } }, diff --git a/metadata/modules/revantageBidAdapter.json b/metadata/modules/revantageBidAdapter.json new file mode 100644 index 00000000000..90eda1e36ad --- /dev/null +++ b/metadata/modules/revantageBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "revantage", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/revcontentBidAdapter.json b/metadata/modules/revcontentBidAdapter.json index 3f45c788da2..4c36e64fbd2 100644 --- a/metadata/modules/revcontentBidAdapter.json +++ b/metadata/modules/revcontentBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sothebys.revcontent.com/static/device_storage.json": { - "timestamp": "2026-01-28T16:30:32.781Z", + "timestamp": "2026-03-02T14:46:06.345Z", "disclosures": [ { "identifier": "__ID", diff --git a/metadata/modules/revnewBidAdapter.json b/metadata/modules/revnewBidAdapter.json index 29fdb8b0198..6a2c2b0b465 100644 --- a/metadata/modules/revnewBidAdapter.json +++ b/metadata/modules/revnewBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://mediafuse.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:32.795Z", + "timestamp": "2026-03-02T14:46:06.391Z", "disclosures": [] } }, diff --git a/metadata/modules/rhythmoneBidAdapter.json b/metadata/modules/rhythmoneBidAdapter.json index 31d017d8c39..b15321eabee 100644 --- a/metadata/modules/rhythmoneBidAdapter.json +++ b/metadata/modules/rhythmoneBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://video.unrulymedia.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:32.929Z", + "timestamp": "2026-03-02T14:46:06.448Z", "disclosures": [] } }, diff --git a/metadata/modules/richaudienceBidAdapter.json b/metadata/modules/richaudienceBidAdapter.json index db4f6fbb7d4..10611865e4a 100644 --- a/metadata/modules/richaudienceBidAdapter.json +++ b/metadata/modules/richaudienceBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdnj.richaudience.com/52a26ab9400b2a9f5aabfa20acf3196g.json": { - "timestamp": "2026-01-28T16:30:33.193Z", + "timestamp": "2026-03-02T14:46:06.805Z", "disclosures": [] } }, diff --git a/metadata/modules/riseBidAdapter.json b/metadata/modules/riseBidAdapter.json index 15a580963ff..3891bd224cb 100644 --- a/metadata/modules/riseBidAdapter.json +++ b/metadata/modules/riseBidAdapter.json @@ -2,11 +2,11 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://d2pm7iglz0b6eq.cloudfront.net/RiseDeviceStorage.json": { - "timestamp": "2026-01-28T16:30:33.264Z", + "timestamp": "2026-03-02T14:46:06.861Z", "disclosures": [] }, "https://spotim-prd-static-assets.s3.amazonaws.com/iab/device-storage.json": { - "timestamp": "2026-01-28T16:30:33.264Z", + "timestamp": "2026-03-02T14:46:06.861Z", "disclosures": [] } }, diff --git a/metadata/modules/rixengineBidAdapter.json b/metadata/modules/rixengineBidAdapter.json index 437a19779b1..980500fae02 100644 --- a/metadata/modules/rixengineBidAdapter.json +++ b/metadata/modules/rixengineBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.algorix.co/gdpr-disclosure.json": { - "timestamp": "2026-01-28T16:30:33.264Z", + "timestamp": "2026-03-02T14:46:06.862Z", "disclosures": [] } }, diff --git a/metadata/modules/rtbhouseBidAdapter.json b/metadata/modules/rtbhouseBidAdapter.json index 20c7edbd123..31714df7b2e 100644 --- a/metadata/modules/rtbhouseBidAdapter.json +++ b/metadata/modules/rtbhouseBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://rtbhouse.com/DeviceStorage.json": { - "timestamp": "2026-01-28T16:30:33.289Z", + "timestamp": "2026-03-02T14:46:06.887Z", "disclosures": [ { "identifier": "_rtbh.*", diff --git a/metadata/modules/rubiconBidAdapter.json b/metadata/modules/rubiconBidAdapter.json index e8f991d7e6d..68ecbd8f4a9 100644 --- a/metadata/modules/rubiconBidAdapter.json +++ b/metadata/modules/rubiconBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://gdpr.rubiconproject.com/dvplus/devicestoragedisclosure.json": { - "timestamp": "2026-01-28T16:30:33.692Z", + "timestamp": "2026-03-02T14:46:07.020Z", "disclosures": [] } }, diff --git a/metadata/modules/scaliburBidAdapter.json b/metadata/modules/scaliburBidAdapter.json index 95100416ca0..b39b894bd9f 100644 --- a/metadata/modules/scaliburBidAdapter.json +++ b/metadata/modules/scaliburBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://legal.overwolf.com/docs/overwolf/website/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:33.929Z", + "timestamp": "2026-03-02T14:46:07.254Z", "disclosures": [ { "identifier": "scluid", diff --git a/metadata/modules/screencoreBidAdapter.json b/metadata/modules/screencoreBidAdapter.json index 19bce2ec18b..1772818cedc 100644 --- a/metadata/modules/screencoreBidAdapter.json +++ b/metadata/modules/screencoreBidAdapter.json @@ -2,8 +2,8 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://screencore.io/tcf.json": { - "timestamp": "2026-01-28T16:30:33.953Z", - "disclosures": null + "timestamp": "2026-03-02T14:46:07.274Z", + "disclosures": [] } }, "components": [ diff --git a/metadata/modules/seedingAllianceBidAdapter.json b/metadata/modules/seedingAllianceBidAdapter.json index fe8d650a43f..801af2fb55e 100644 --- a/metadata/modules/seedingAllianceBidAdapter.json +++ b/metadata/modules/seedingAllianceBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s.nativendo.de/cdn/asset/tcf/purpose-specific-storage-and-access-information.json": { - "timestamp": "2026-01-28T16:30:36.548Z", + "timestamp": "2026-03-02T14:46:07.339Z", "disclosures": [] } }, diff --git a/metadata/modules/seedtagBidAdapter.json b/metadata/modules/seedtagBidAdapter.json index dc5a53845ed..3ad01be8a3a 100644 --- a/metadata/modules/seedtagBidAdapter.json +++ b/metadata/modules/seedtagBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.seedtag.com/vendor.json": { - "timestamp": "2026-01-28T16:30:36.576Z", + "timestamp": "2026-03-02T14:46:07.366Z", "disclosures": [] } }, diff --git a/metadata/modules/semantiqRtdProvider.json b/metadata/modules/semantiqRtdProvider.json index e03a5cffba7..296ab8e1865 100644 --- a/metadata/modules/semantiqRtdProvider.json +++ b/metadata/modules/semantiqRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://audienzz.com/device_storage_disclosure_vendor_783.json": { - "timestamp": "2026-01-28T16:30:36.576Z", + "timestamp": "2026-03-02T14:46:07.366Z", "disclosures": [] } }, diff --git a/metadata/modules/setupadBidAdapter.json b/metadata/modules/setupadBidAdapter.json index 9114eb7ffec..20bb4dab06f 100644 --- a/metadata/modules/setupadBidAdapter.json +++ b/metadata/modules/setupadBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cookies.stpd.cloud/disclosures.json": { - "timestamp": "2026-01-28T16:30:36.628Z", + "timestamp": "2026-03-02T14:46:07.471Z", "disclosures": [] } }, diff --git a/metadata/modules/sevioBidAdapter.json b/metadata/modules/sevioBidAdapter.json index 9c5e2a82b2a..4326d208d40 100644 --- a/metadata/modules/sevioBidAdapter.json +++ b/metadata/modules/sevioBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sevio.com/tcf.json": { - "timestamp": "2026-01-28T16:30:36.792Z", + "timestamp": "2026-03-02T14:46:07.609Z", "disclosures": [] } }, diff --git a/metadata/modules/sharedIdSystem.json b/metadata/modules/sharedIdSystem.json index deda98910f7..cda116dbd54 100644 --- a/metadata/modules/sharedIdSystem.json +++ b/metadata/modules/sharedIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/sharedId-optout.json": { - "timestamp": "2026-01-28T16:30:36.949Z", + "timestamp": "2026-03-02T14:46:07.758Z", "disclosures": [ { "identifier": "_pubcid_optout", diff --git a/metadata/modules/sharethroughBidAdapter.json b/metadata/modules/sharethroughBidAdapter.json index 5d835a1ba39..8c2ce012b1d 100644 --- a/metadata/modules/sharethroughBidAdapter.json +++ b/metadata/modules/sharethroughBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://assets.sharethrough.com/gvl.json": { - "timestamp": "2026-01-28T16:30:36.949Z", + "timestamp": "2026-03-02T14:46:07.758Z", "disclosures": [] } }, diff --git a/metadata/modules/showheroes-bsBidAdapter.json b/metadata/modules/showheroes-bsBidAdapter.json index 7dcee4cef53..9abcf1c23b4 100644 --- a/metadata/modules/showheroes-bsBidAdapter.json +++ b/metadata/modules/showheroes-bsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://static-origin.showheroes.com/gvl_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:36.971Z", + "timestamp": "2026-03-02T14:46:07.777Z", "disclosures": [] } }, diff --git a/metadata/modules/silvermobBidAdapter.json b/metadata/modules/silvermobBidAdapter.json index 21743e158e4..c5aa4e9afcb 100644 --- a/metadata/modules/silvermobBidAdapter.json +++ b/metadata/modules/silvermobBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://silvermob.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:37.398Z", + "timestamp": "2026-03-02T14:46:08.247Z", "disclosures": [] } }, diff --git a/metadata/modules/sirdataRtdProvider.json b/metadata/modules/sirdataRtdProvider.json index 292ad9c1408..348ce7f9fd4 100644 --- a/metadata/modules/sirdataRtdProvider.json +++ b/metadata/modules/sirdataRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.sirdata.eu/sirdata_device_storage_disclosure.json": { - "timestamp": "2026-01-28T16:30:37.414Z", + "timestamp": "2026-03-02T14:46:08.262Z", "disclosures": [] } }, diff --git a/metadata/modules/smaatoBidAdapter.json b/metadata/modules/smaatoBidAdapter.json index 35d7af131ec..413fb0f4ca3 100644 --- a/metadata/modules/smaatoBidAdapter.json +++ b/metadata/modules/smaatoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://resources.smaato.com/hubfs/Smaato/IAB/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:37.710Z", + "timestamp": "2026-03-02T14:46:08.585Z", "disclosures": [] } }, diff --git a/metadata/modules/smartadserverBidAdapter.json b/metadata/modules/smartadserverBidAdapter.json index a1ed3e1f8bd..a1c3212113e 100644 --- a/metadata/modules/smartadserverBidAdapter.json +++ b/metadata/modules/smartadserverBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://apps.smartadserver.com/device-storage-disclosures/equativDeviceStorageDisclosures.json": { - "timestamp": "2026-01-28T16:30:37.818Z", + "timestamp": "2026-03-02T14:46:08.665Z", "disclosures": [] } }, diff --git a/metadata/modules/smartxBidAdapter.json b/metadata/modules/smartxBidAdapter.json index 2bbf3c45927..06854dd00c3 100644 --- a/metadata/modules/smartxBidAdapter.json +++ b/metadata/modules/smartxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.smartclip.net/iab/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:37.819Z", + "timestamp": "2026-03-02T14:46:08.666Z", "disclosures": [] } }, diff --git a/metadata/modules/smartyadsBidAdapter.json b/metadata/modules/smartyadsBidAdapter.json index c56d5f330e6..202d8317bad 100644 --- a/metadata/modules/smartyadsBidAdapter.json +++ b/metadata/modules/smartyadsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://smartyads.com/tcf.json": { - "timestamp": "2026-01-28T16:30:37.844Z", + "timestamp": "2026-03-02T14:46:08.685Z", "disclosures": [] } }, diff --git a/metadata/modules/smilewantedBidAdapter.json b/metadata/modules/smilewantedBidAdapter.json index 5c3b44c8296..7b14099448a 100644 --- a/metadata/modules/smilewantedBidAdapter.json +++ b/metadata/modules/smilewantedBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://smilewanted.com/vendor-device-storage-disclosures.json": { - "timestamp": "2026-01-28T16:30:37.886Z", + "timestamp": "2026-03-02T14:46:08.723Z", "disclosures": [] } }, diff --git a/metadata/modules/snigelBidAdapter.json b/metadata/modules/snigelBidAdapter.json index 68d1c0c2815..ef1115d5554 100644 --- a/metadata/modules/snigelBidAdapter.json +++ b/metadata/modules/snigelBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.snigelweb.com/gvl/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:38.328Z", + "timestamp": "2026-03-02T14:46:09.181Z", "disclosures": [] } }, diff --git a/metadata/modules/sonaradsBidAdapter.json b/metadata/modules/sonaradsBidAdapter.json index b41bae638fe..b75cfe08e7c 100644 --- a/metadata/modules/sonaradsBidAdapter.json +++ b/metadata/modules/sonaradsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bridgeupp.com/device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:38.465Z", + "timestamp": "2026-03-02T14:46:09.233Z", "disclosures": [] } }, diff --git a/metadata/modules/sonobiBidAdapter.json b/metadata/modules/sonobiBidAdapter.json index bef53619e19..6ebb47d3e03 100644 --- a/metadata/modules/sonobiBidAdapter.json +++ b/metadata/modules/sonobiBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://sonobi.com/tcf2-device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:38.695Z", + "timestamp": "2026-03-02T14:46:09.460Z", "disclosures": [] } }, diff --git a/metadata/modules/sovrnBidAdapter.json b/metadata/modules/sovrnBidAdapter.json index ae4dc05951d..0abfb9c0b85 100644 --- a/metadata/modules/sovrnBidAdapter.json +++ b/metadata/modules/sovrnBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.sovrn.com/tcf-cookie-disclosure/disclosure.json": { - "timestamp": "2026-01-28T16:30:38.930Z", + "timestamp": "2026-03-02T14:46:09.690Z", "disclosures": [] } }, diff --git a/metadata/modules/sparteoBidAdapter.json b/metadata/modules/sparteoBidAdapter.json index 4f549fdb2e4..b89e3d7a3d7 100644 --- a/metadata/modules/sparteoBidAdapter.json +++ b/metadata/modules/sparteoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bid.bricks-co.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:38.952Z", + "timestamp": "2026-03-02T14:46:09.709Z", "disclosures": [ { "identifier": "fastCMP-addtlConsent", diff --git a/metadata/modules/ssmasBidAdapter.json b/metadata/modules/ssmasBidAdapter.json index ccc832d962a..be24aefdf2e 100644 --- a/metadata/modules/ssmasBidAdapter.json +++ b/metadata/modules/ssmasBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://semseoymas.com/iab.json": { - "timestamp": "2026-01-28T16:30:39.228Z", + "timestamp": "2026-03-02T14:46:09.989Z", "disclosures": null } }, diff --git a/metadata/modules/sspBCBidAdapter.json b/metadata/modules/sspBCBidAdapter.json index db6d59ff097..a99dc0c8ea5 100644 --- a/metadata/modules/sspBCBidAdapter.json +++ b/metadata/modules/sspBCBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ssp.wp.pl/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:39.834Z", + "timestamp": "2026-03-02T14:46:10.636Z", "disclosures": null } }, diff --git a/metadata/modules/stackadaptBidAdapter.json b/metadata/modules/stackadaptBidAdapter.json index f0049ce614b..6a53c79a6f2 100644 --- a/metadata/modules/stackadaptBidAdapter.json +++ b/metadata/modules/stackadaptBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://s3.amazonaws.com/stackadapt_public/disclosures.json": { - "timestamp": "2026-01-28T16:30:39.835Z", + "timestamp": "2026-03-02T14:46:10.637Z", "disclosures": [ { "identifier": "sa-camp-*", @@ -62,6 +62,17 @@ 4 ] }, + { + "identifier": "sa-user-id-v4", + "type": "cookie", + "maxAgeSeconds": 31536000, + "cookieRefresh": false, + "purposes": [ + 1, + 3, + 4 + ] + }, { "identifier": "sa-user-id", "type": "web", @@ -84,6 +95,17 @@ 4 ] }, + { + "identifier": "sa-user-id-v4", + "type": "web", + "maxAgeSeconds": null, + "cookieRefresh": false, + "purposes": [ + 1, + 3, + 4 + ] + }, { "identifier": "sa-camp-*", "type": "web", diff --git a/metadata/modules/startioBidAdapter.json b/metadata/modules/startioBidAdapter.json index b2288e475a3..62dadaf9188 100644 --- a/metadata/modules/startioBidAdapter.json +++ b/metadata/modules/startioBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://info.startappservice.com/tcf/start.io_domains.json": { - "timestamp": "2026-01-28T16:30:39.868Z", + "timestamp": "2026-03-02T14:46:10.672Z", "disclosures": [] } }, diff --git a/metadata/modules/stroeerCoreBidAdapter.json b/metadata/modules/stroeerCoreBidAdapter.json index d665b481f92..4830347118e 100644 --- a/metadata/modules/stroeerCoreBidAdapter.json +++ b/metadata/modules/stroeerCoreBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.stroeer.de/StroeerSSP_deviceStorage.json": { - "timestamp": "2026-01-28T16:30:39.889Z", + "timestamp": "2026-03-02T14:46:10.688Z", "disclosures": [] } }, diff --git a/metadata/modules/stvBidAdapter.json b/metadata/modules/stvBidAdapter.json index d1ce12c1ae4..0409bb9984d 100644 --- a/metadata/modules/stvBidAdapter.json +++ b/metadata/modules/stvBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.adtech.app/gen/deviceStorageDisclosure/stv.json": { - "timestamp": "2026-01-28T16:30:40.266Z", + "timestamp": "2026-03-02T14:46:11.041Z", "disclosures": [] } }, diff --git a/metadata/modules/sublimeBidAdapter.json b/metadata/modules/sublimeBidAdapter.json index 77f960e3892..babdae509ce 100644 --- a/metadata/modules/sublimeBidAdapter.json +++ b/metadata/modules/sublimeBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://gdpr.ayads.co/cookiepolicy.json": { - "timestamp": "2026-01-28T16:30:40.913Z", + "timestamp": "2026-03-02T14:46:11.678Z", "disclosures": [ { "identifier": "dnt", diff --git a/metadata/modules/taboolaBidAdapter.json b/metadata/modules/taboolaBidAdapter.json index 07e38d4e2f3..c829cd46687 100644 --- a/metadata/modules/taboolaBidAdapter.json +++ b/metadata/modules/taboolaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://accessrequest.taboola.com/iab-tcf-v2-disclosure.json": { - "timestamp": "2026-01-28T16:30:41.174Z", + "timestamp": "2026-03-02T14:46:11.938Z", "disclosures": [ { "identifier": "trc_cookie_storage", diff --git a/metadata/modules/taboolaIdSystem.json b/metadata/modules/taboolaIdSystem.json index 5192f0b5a53..6fcf6a5ec28 100644 --- a/metadata/modules/taboolaIdSystem.json +++ b/metadata/modules/taboolaIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://accessrequest.taboola.com/iab-tcf-v2-disclosure.json": { - "timestamp": "2026-01-28T16:30:41.833Z", + "timestamp": "2026-03-02T14:46:12.149Z", "disclosures": [ { "identifier": "trc_cookie_storage", diff --git a/metadata/modules/tadvertisingBidAdapter.json b/metadata/modules/tadvertisingBidAdapter.json index a3cb6303200..35fb4310c9c 100644 --- a/metadata/modules/tadvertisingBidAdapter.json +++ b/metadata/modules/tadvertisingBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tcf.emetriq.de/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:41.834Z", + "timestamp": "2026-03-02T14:46:12.150Z", "disclosures": [] } }, diff --git a/metadata/modules/tappxBidAdapter.json b/metadata/modules/tappxBidAdapter.json index a487b12cb7d..6a1843cea0d 100644 --- a/metadata/modules/tappxBidAdapter.json +++ b/metadata/modules/tappxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://tappx.com/devicestorage.json": { - "timestamp": "2026-01-28T16:30:41.858Z", + "timestamp": "2026-03-02T14:46:12.408Z", "disclosures": [] } }, diff --git a/metadata/modules/targetVideoBidAdapter.json b/metadata/modules/targetVideoBidAdapter.json index ec93fdb78b9..d785b33951a 100644 --- a/metadata/modules/targetVideoBidAdapter.json +++ b/metadata/modules/targetVideoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://target-video.com/vendors-device-storage-and-operational-disclosures.json": { - "timestamp": "2026-01-28T16:30:41.884Z", + "timestamp": "2026-03-02T14:46:12.436Z", "disclosures": [ { "identifier": "brid_location", diff --git a/metadata/modules/teadsBidAdapter.json b/metadata/modules/teadsBidAdapter.json index daed112213d..669db4c09d6 100644 --- a/metadata/modules/teadsBidAdapter.json +++ b/metadata/modules/teadsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://iab-cookie-disclosure.teads.tv/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:41.885Z", + "timestamp": "2026-03-02T14:46:12.437Z", "disclosures": [] } }, diff --git a/metadata/modules/teadsIdSystem.json b/metadata/modules/teadsIdSystem.json index 8e927eaff33..a84486229b0 100644 --- a/metadata/modules/teadsIdSystem.json +++ b/metadata/modules/teadsIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://iab-cookie-disclosure.teads.tv/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:41.907Z", + "timestamp": "2026-03-02T14:46:12.457Z", "disclosures": [] } }, diff --git a/metadata/modules/tealBidAdapter.json b/metadata/modules/tealBidAdapter.json index 704d75aadae..fb6a14599bd 100644 --- a/metadata/modules/tealBidAdapter.json +++ b/metadata/modules/tealBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://c.bids.ws/iab/disclosures.json": { - "timestamp": "2026-01-28T16:30:41.907Z", + "timestamp": "2026-03-02T14:46:12.457Z", "disclosures": [] } }, diff --git a/metadata/modules/teqBlazeSalesAgentBidAdapter.json b/metadata/modules/teqBlazeSalesAgentBidAdapter.json new file mode 100644 index 00000000000..2442df240d1 --- /dev/null +++ b/metadata/modules/teqBlazeSalesAgentBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "teqBlazeSalesAgent", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/tncIdSystem.json b/metadata/modules/tncIdSystem.json index 647cab4a5cc..dd50f1b4493 100644 --- a/metadata/modules/tncIdSystem.json +++ b/metadata/modules/tncIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://js.tncid.app/iab-tcf-device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:41.941Z", + "timestamp": "2026-03-02T14:46:12.515Z", "disclosures": [] } }, diff --git a/metadata/modules/topicsFpdModule.json b/metadata/modules/topicsFpdModule.json index 95987763bde..e4683b84727 100644 --- a/metadata/modules/topicsFpdModule.json +++ b/metadata/modules/topicsFpdModule.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/topicsFpdModule.json": { - "timestamp": "2026-01-28T16:29:58.214Z", + "timestamp": "2026-03-02T14:44:46.316Z", "disclosures": [ { "identifier": "prebid:topics", diff --git a/metadata/modules/toponBidAdapter.json b/metadata/modules/toponBidAdapter.json index d008f59f2dd..719b4868651 100644 --- a/metadata/modules/toponBidAdapter.json +++ b/metadata/modules/toponBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://mores.toponad.net/tmp/tpn/toponads_tcf_disclosure.json": { - "timestamp": "2026-01-28T16:30:41.959Z", + "timestamp": "2026-03-02T14:46:12.534Z", "disclosures": [] } }, diff --git a/metadata/modules/tripleliftBidAdapter.json b/metadata/modules/tripleliftBidAdapter.json index 94cc97bcf8a..ae8f461ead0 100644 --- a/metadata/modules/tripleliftBidAdapter.json +++ b/metadata/modules/tripleliftBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://triplelift.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:41.986Z", + "timestamp": "2026-03-02T14:46:12.661Z", "disclosures": [] } }, diff --git a/metadata/modules/ttdBidAdapter.json b/metadata/modules/ttdBidAdapter.json index d6d3b8cebec..825c0388f7a 100644 --- a/metadata/modules/ttdBidAdapter.json +++ b/metadata/modules/ttdBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ttd-misc-public-assets.s3.us-west-2.amazonaws.com/deviceStorageDisclosureURL.json": { - "timestamp": "2026-01-28T16:30:42.047Z", + "timestamp": "2026-03-02T14:46:12.692Z", "disclosures": [] } }, diff --git a/metadata/modules/twistDigitalBidAdapter.json b/metadata/modules/twistDigitalBidAdapter.json index 9d23eddf753..fc4095423c5 100644 --- a/metadata/modules/twistDigitalBidAdapter.json +++ b/metadata/modules/twistDigitalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://twistdigital.net/iab.json": { - "timestamp": "2026-01-28T16:30:42.047Z", + "timestamp": "2026-03-02T14:46:12.692Z", "disclosures": [ { "identifier": "vdzj1_{id}", diff --git a/metadata/modules/underdogmediaBidAdapter.json b/metadata/modules/underdogmediaBidAdapter.json index fefaee8ca12..dbd497898d7 100644 --- a/metadata/modules/underdogmediaBidAdapter.json +++ b/metadata/modules/underdogmediaBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bid.underdog.media/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:42.135Z", + "timestamp": "2026-03-02T14:46:12.772Z", "disclosures": [] } }, diff --git a/metadata/modules/undertoneBidAdapter.json b/metadata/modules/undertoneBidAdapter.json index eab5cb0d139..0b02483de93 100644 --- a/metadata/modules/undertoneBidAdapter.json +++ b/metadata/modules/undertoneBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.undertone.com/js/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:42.159Z", + "timestamp": "2026-03-02T14:46:12.790Z", "disclosures": [] } }, diff --git a/metadata/modules/unifiedIdSystem.json b/metadata/modules/unifiedIdSystem.json index c036a28e618..cc27f390b4d 100644 --- a/metadata/modules/unifiedIdSystem.json +++ b/metadata/modules/unifiedIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ttd-misc-public-assets.s3.us-west-2.amazonaws.com/deviceStorageDisclosureURL.json": { - "timestamp": "2026-01-28T16:30:42.227Z", + "timestamp": "2026-03-02T14:46:12.878Z", "disclosures": [] } }, diff --git a/metadata/modules/unrulyBidAdapter.json b/metadata/modules/unrulyBidAdapter.json index e2175b3f549..5d00220a7b8 100644 --- a/metadata/modules/unrulyBidAdapter.json +++ b/metadata/modules/unrulyBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://video.unrulymedia.com/deviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:42.227Z", + "timestamp": "2026-03-02T14:46:12.878Z", "disclosures": [] } }, diff --git a/metadata/modules/userId.json b/metadata/modules/userId.json index 4cb33e6f4a1..a7288064da5 100644 --- a/metadata/modules/userId.json +++ b/metadata/modules/userId.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/userId-optout.json": { - "timestamp": "2026-01-28T16:29:58.216Z", + "timestamp": "2026-03-02T14:44:46.317Z", "disclosures": [ { "identifier": "_pbjs_id_optout", diff --git a/metadata/modules/utiqIdSystem.json b/metadata/modules/utiqIdSystem.json index 071faa17400..6e7e629b0ac 100644 --- a/metadata/modules/utiqIdSystem.json +++ b/metadata/modules/utiqIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/modules/utiqDeviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:42.227Z", + "timestamp": "2026-03-02T14:46:12.878Z", "disclosures": [ { "identifier": "utiqPass", diff --git a/metadata/modules/utiqMtpIdSystem.json b/metadata/modules/utiqMtpIdSystem.json index 2df7ca96f1b..8e9e76248b8 100644 --- a/metadata/modules/utiqMtpIdSystem.json +++ b/metadata/modules/utiqMtpIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/modules/utiqDeviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:42.229Z", + "timestamp": "2026-03-02T14:46:12.879Z", "disclosures": [ { "identifier": "utiqPass", diff --git a/metadata/modules/validationFpdModule.json b/metadata/modules/validationFpdModule.json index ca2ae6a8883..05f5921394d 100644 --- a/metadata/modules/validationFpdModule.json +++ b/metadata/modules/validationFpdModule.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.jsdelivr.net/gh/prebid/Prebid.js/metadata/disclosures/prebid/sharedId-optout.json": { - "timestamp": "2026-01-28T16:29:58.215Z", + "timestamp": "2026-03-02T14:44:46.316Z", "disclosures": [ { "identifier": "_pubcid_optout", diff --git a/metadata/modules/valuadBidAdapter.json b/metadata/modules/valuadBidAdapter.json index 9141c9dceda..4bcb9939955 100644 --- a/metadata/modules/valuadBidAdapter.json +++ b/metadata/modules/valuadBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.valuad.cloud/tcfdevice.json": { - "timestamp": "2026-01-28T16:30:42.229Z", + "timestamp": "2026-03-02T14:46:12.879Z", "disclosures": [] } }, diff --git a/metadata/modules/verbenBidAdapter.json b/metadata/modules/verbenBidAdapter.json new file mode 100644 index 00000000000..47a939ac97a --- /dev/null +++ b/metadata/modules/verbenBidAdapter.json @@ -0,0 +1,13 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": {}, + "components": [ + { + "componentType": "bidder", + "componentName": "verben", + "aliasOf": null, + "gvlid": null, + "disclosureURL": null + } + ] +} \ No newline at end of file diff --git a/metadata/modules/vidazooBidAdapter.json b/metadata/modules/vidazooBidAdapter.json index 8cfb42a6329..d2fee191de4 100644 --- a/metadata/modules/vidazooBidAdapter.json +++ b/metadata/modules/vidazooBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://vidazoo.com/gdpr-tcf/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:42.541Z", + "timestamp": "2026-03-02T14:46:13.094Z", "disclosures": [ { "identifier": "ck48wz12sqj7", diff --git a/metadata/modules/vidoomyBidAdapter.json b/metadata/modules/vidoomyBidAdapter.json index a15352d7209..4902540cf3f 100644 --- a/metadata/modules/vidoomyBidAdapter.json +++ b/metadata/modules/vidoomyBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://vidoomy.com/storageurl/devicestoragediscurl.json": { - "timestamp": "2026-01-28T16:30:42.610Z", + "timestamp": "2026-03-02T14:46:13.172Z", "disclosures": [] } }, diff --git a/metadata/modules/viouslyBidAdapter.json b/metadata/modules/viouslyBidAdapter.json index a9ba5b1ea69..c26728473ea 100644 --- a/metadata/modules/viouslyBidAdapter.json +++ b/metadata/modules/viouslyBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://bid.bricks-co.com/.well-known/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:42.721Z", + "timestamp": "2026-03-02T14:46:18.010Z", "disclosures": [ { "identifier": "fastCMP-addtlConsent", diff --git a/metadata/modules/visxBidAdapter.json b/metadata/modules/visxBidAdapter.json index 82a358c4252..de208d4fa21 100644 --- a/metadata/modules/visxBidAdapter.json +++ b/metadata/modules/visxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.yoc.com/visx/sellers/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:42.722Z", + "timestamp": "2026-03-02T14:46:18.011Z", "disclosures": [ { "identifier": "__vads", diff --git a/metadata/modules/vlybyBidAdapter.json b/metadata/modules/vlybyBidAdapter.json index f981ce6b7d8..a8a8be09eb6 100644 --- a/metadata/modules/vlybyBidAdapter.json +++ b/metadata/modules/vlybyBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.vlyby.com/conf/iab/gvl.json": { - "timestamp": "2026-01-28T16:30:42.933Z", + "timestamp": "2026-03-02T14:46:18.324Z", "disclosures": [] } }, diff --git a/metadata/modules/voxBidAdapter.json b/metadata/modules/voxBidAdapter.json index 534d5aa909f..71d1adacb65 100644 --- a/metadata/modules/voxBidAdapter.json +++ b/metadata/modules/voxBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://st.hybrid.ai/policy/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:43.350Z", + "timestamp": "2026-03-02T14:46:18.645Z", "disclosures": [] } }, diff --git a/metadata/modules/vrtcalBidAdapter.json b/metadata/modules/vrtcalBidAdapter.json index 98b4bf97df2..492cc4a9c29 100644 --- a/metadata/modules/vrtcalBidAdapter.json +++ b/metadata/modules/vrtcalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://vrtcal.com/docs/gdpr-tcf-disclosures.json": { - "timestamp": "2026-01-28T16:30:43.350Z", + "timestamp": "2026-03-02T14:46:18.645Z", "disclosures": [] } }, diff --git a/metadata/modules/vuukleBidAdapter.json b/metadata/modules/vuukleBidAdapter.json index 82f8197b440..9ff99596a87 100644 --- a/metadata/modules/vuukleBidAdapter.json +++ b/metadata/modules/vuukleBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn.vuukle.com/data-privacy/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:43.368Z", + "timestamp": "2026-03-02T14:46:18.662Z", "disclosures": [ { "identifier": "vuukle_token", diff --git a/metadata/modules/weboramaRtdProvider.json b/metadata/modules/weboramaRtdProvider.json index 942e28d93a9..3d5c7c23945 100644 --- a/metadata/modules/weboramaRtdProvider.json +++ b/metadata/modules/weboramaRtdProvider.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://weborama.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:43.680Z", + "timestamp": "2026-03-02T14:46:18.964Z", "disclosures": [] } }, diff --git a/metadata/modules/welectBidAdapter.json b/metadata/modules/welectBidAdapter.json index bf17a459ac4..f6fe924992e 100644 --- a/metadata/modules/welectBidAdapter.json +++ b/metadata/modules/welectBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://www.welect.de/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:43.935Z", + "timestamp": "2026-03-02T14:46:19.465Z", "disclosures": [] } }, diff --git a/metadata/modules/yahooAdsBidAdapter.json b/metadata/modules/yahooAdsBidAdapter.json index 70f246f825d..214ac134bbe 100644 --- a/metadata/modules/yahooAdsBidAdapter.json +++ b/metadata/modules/yahooAdsBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://meta.legal.yahoo.com/iab-tcf/v2/device-storage-disclosure.json": { - "timestamp": "2026-01-28T16:30:44.341Z", + "timestamp": "2026-03-02T14:46:19.840Z", "disclosures": [ { "identifier": "vmcid", diff --git a/metadata/modules/yaleoBidAdapter.json b/metadata/modules/yaleoBidAdapter.json new file mode 100644 index 00000000000..b78e431d9c6 --- /dev/null +++ b/metadata/modules/yaleoBidAdapter.json @@ -0,0 +1,18 @@ +{ + "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", + "disclosures": { + "https://audienzz.com/device_storage_disclosure_vendor_783.json": { + "timestamp": "2026-03-02T14:46:19.841Z", + "disclosures": [] + } + }, + "components": [ + { + "componentType": "bidder", + "componentName": "yaleo", + "aliasOf": null, + "gvlid": 783, + "disclosureURL": "https://audienzz.com/device_storage_disclosure_vendor_783.json" + } + ] +} \ No newline at end of file diff --git a/metadata/modules/yieldlabBidAdapter.json b/metadata/modules/yieldlabBidAdapter.json index 546bfd19305..52962311fa8 100644 --- a/metadata/modules/yieldlabBidAdapter.json +++ b/metadata/modules/yieldlabBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://ad.yieldlab.net/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:44.342Z", + "timestamp": "2026-03-02T14:46:19.841Z", "disclosures": [] } }, diff --git a/metadata/modules/yieldloveBidAdapter.json b/metadata/modules/yieldloveBidAdapter.json index d311669356b..e0f3e660ae6 100644 --- a/metadata/modules/yieldloveBidAdapter.json +++ b/metadata/modules/yieldloveBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://cdn-a.yieldlove.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:44.472Z", + "timestamp": "2026-03-02T14:46:20.279Z", "disclosures": [ { "identifier": "session_id", diff --git a/metadata/modules/yieldmoBidAdapter.json b/metadata/modules/yieldmoBidAdapter.json index 0f2052e3cf4..ce311353d52 100644 --- a/metadata/modules/yieldmoBidAdapter.json +++ b/metadata/modules/yieldmoBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://devicestoragedisclosureurl.yieldmo.com/deviceStorage.json": { - "timestamp": "2026-01-28T16:30:44.497Z", + "timestamp": "2026-03-02T14:46:20.302Z", "disclosures": [] } }, diff --git a/metadata/modules/zeotapIdPlusIdSystem.json b/metadata/modules/zeotapIdPlusIdSystem.json index 6105ace2968..3f9dfb1b424 100644 --- a/metadata/modules/zeotapIdPlusIdSystem.json +++ b/metadata/modules/zeotapIdPlusIdSystem.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://spl.zeotap.com/assets/iab-disclosure.json": { - "timestamp": "2026-01-28T16:30:44.585Z", + "timestamp": "2026-03-02T14:46:20.390Z", "disclosures": [] } }, diff --git a/metadata/modules/zeta_globalBidAdapter.json b/metadata/modules/zeta_globalBidAdapter.json index 274bd4c75f0..f215e1e0463 100644 --- a/metadata/modules/zeta_globalBidAdapter.json +++ b/metadata/modules/zeta_globalBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://zetaglobal.com/ZetaDeviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:44.708Z", + "timestamp": "2026-03-02T14:46:20.525Z", "disclosures": [] } }, diff --git a/metadata/modules/zeta_global_sspBidAdapter.json b/metadata/modules/zeta_global_sspBidAdapter.json index e51e6fd80ec..517fd76fb4c 100644 --- a/metadata/modules/zeta_global_sspBidAdapter.json +++ b/metadata/modules/zeta_global_sspBidAdapter.json @@ -2,7 +2,7 @@ "NOTICE": "do not edit - this file is autogenerated by `gulp update-metadata`", "disclosures": { "https://zetaglobal.com/ZetaDeviceStorageDisclosure.json": { - "timestamp": "2026-01-28T16:30:44.784Z", + "timestamp": "2026-03-02T14:46:20.656Z", "disclosures": [] } }, diff --git a/modules/.submodules.json b/modules/.submodules.json index c6274fdcbfd..c6b0db32e78 100644 --- a/modules/.submodules.json +++ b/modules/.submodules.json @@ -32,6 +32,7 @@ "kinessoIdSystem", "liveIntentIdSystem", "lmpIdSystem", + "locIdSystem", "lockrAIMIdSystem", "lotamePanoramaIdSystem", "merkleIdSystem", @@ -117,6 +118,7 @@ "optimeraRtdProvider", "overtoneRtdProvider", "oxxionRtdProvider", + "panxoRtdProvider", "permutiveRtdProvider", "pubmaticRtdProvider", "pubxaiRtdProvider", @@ -147,4 +149,4 @@ "topLevelPaapi" ] } -} \ No newline at end of file +} diff --git a/modules/33acrossAnalyticsAdapter.js b/modules/33acrossAnalyticsAdapter.js index ad9b33d6762..06beb2bfa08 100644 --- a/modules/33acrossAnalyticsAdapter.js +++ b/modules/33acrossAnalyticsAdapter.js @@ -337,7 +337,7 @@ function createReportFromCache(analyticsCache, completedAuctionId) { src: 'pbjs', analyticsVersion: ANALYTICS_VERSION, pbjsVersion: '$prebid.version$', // Replaced by build script - auctions: [ auctions[completedAuctionId] ], + auctions: [auctions[completedAuctionId]], } if (uspDataHandler.getConsentData()) { report.usPrivacy = uspDataHandler.getConsentData(); diff --git a/modules/33acrossBidAdapter.js b/modules/33acrossBidAdapter.js index 3c2c364fafd..d072cd7c1f7 100644 --- a/modules/33acrossBidAdapter.js +++ b/modules/33acrossBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; import { deepAccess, getWindowSelf, @@ -11,12 +11,12 @@ import { mergeDeep, uniques } from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { isSlotMatchingAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { percentInView } from '../libraries/percentInView/percentInView.js'; -import {getMinSize} from '../libraries/sizeUtils/sizeUtils.js'; -import {isIframe} from '../libraries/omsUtils/index.js'; +import { getMinSize } from '../libraries/sizeUtils/sizeUtils.js'; +import { isIframe } from '../libraries/omsUtils/index.js'; // **************************** UTILS ************************** // const BIDDER_CODE = '33across'; @@ -81,8 +81,8 @@ function getTTXConfig() { } function collapseFalsy(obj) { - const data = Array.isArray(obj) ? [ ...obj ] : Object.assign({}, obj); - const falsyValuesToCollapse = [ null, undefined, '' ]; + const data = Array.isArray(obj) ? [...obj] : Object.assign({}, obj); + const falsyValuesToCollapse = [null, undefined, '']; for (const key in data) { if (falsyValuesToCollapse.includes(data[key]) || (Array.isArray(data[key]) && data[key].length === 0)) { @@ -166,7 +166,7 @@ function hasValidVideoProperties(bid) { } // If placement if defined, it must be a number - if ([ videoParams.placement, videoParams.plcmt ].some(value => ( + if ([videoParams.placement, videoParams.plcmt].some(value => ( typeof value !== 'undefined' && typeof value !== 'number' ))) { @@ -187,7 +187,7 @@ function hasValidVideoProperties(bid) { // **************************** BUILD REQUESTS *************************** // function buildRequests(bidRequests, bidderRequest = {}) { - const convertedORTB = converter.toORTB({bidRequests, bidderRequest}); + const convertedORTB = converter.toORTB({ bidRequests, bidderRequest }); const { ttxSettings, gdprConsent, @@ -280,10 +280,10 @@ function _createServerRequest({ bidRequests, gdprConsent = {}, referer, ttxSetti ext: { ttx: { prebidStartedAt: Date.now(), - caller: [ { + caller: [{ 'name': 'prebidjs', 'version': '$prebid.version$' - } ] + }] } }, test: test === 1 ? 1 : null @@ -336,7 +336,7 @@ function _buildImpORTB(bidRequest) { // BUILD REQUESTS: SIZE INFERENCE function _transformSizes(sizes) { if (isArray(sizes) && sizes.length === 2 && !isArray(sizes[0])) { - return [ _getSize(sizes) ]; + return [_getSize(sizes)]; } return sizes.map(_getSize); @@ -387,7 +387,7 @@ function _buildBannerORTB(bidRequest) { formatExt = { ext: { ttx: { - bidfloors: [ bidfloors ] + bidfloors: [bidfloors] } } } @@ -444,7 +444,7 @@ function _buildVideoORTB(bidRequest) { Object.assign(video, { ext: { ttx: { - bidfloors: [ bidfloors ] + bidfloors: [bidfloors] } } }); @@ -459,7 +459,7 @@ function _getBidFloors(bidRequest, size, mediaType) { const bidFloors = bidRequest.getFloor({ currency: CURRENCY, mediaType, - size: [ size.w, size.h ] + size: [size.w, size.h] }); if (!isNaN(bidFloors?.floor) && (bidFloors?.currency === CURRENCY)) { @@ -644,7 +644,7 @@ export const spec = { code: BIDDER_CODE, aliases: BIDDER_ALIASES, - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], gvlid: GVLID, isBidRequestValid, buildRequests, diff --git a/modules/33acrossIdSystem.js b/modules/33acrossIdSystem.js index f0b58297da9..707b1cc9ce5 100644 --- a/modules/33acrossIdSystem.js +++ b/modules/33acrossIdSystem.js @@ -170,7 +170,7 @@ function filterEnabledSupplementalIds({ tp, fp, hem }, { storeFpid, storeTpid, e } function updateSupplementalIdStorage(supplementalId, storageConfig) { - const [ key, id, clear ] = supplementalId; + const [key, id, clear] = supplementalId; if (clear) { deleteFromStorage(key); @@ -222,7 +222,7 @@ export const thirtyThreeAcrossIdSubmodule = { * @param {SubmoduleConfig} [config] * @returns {IdResponse|undefined} */ - getId({ params = { }, enabledStorageTypes = [], storage: storageConfig = {} }, {gdpr: gdprConsentData} = {}) { + getId({ params = { }, enabledStorageTypes = [], storage: storageConfig = {} }, { gdpr: gdprConsentData } = {}) { if (typeof params.pid !== 'string') { logError(`${MODULE_NAME}: Submodule requires a partner ID to be defined`); diff --git a/modules/51DegreesRtdProvider.js b/modules/51DegreesRtdProvider.js index f5c76357ffc..f8542365dbd 100644 --- a/modules/51DegreesRtdProvider.js +++ b/modules/51DegreesRtdProvider.js @@ -1,6 +1,6 @@ import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {submodule} from '../src/hook.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { submodule } from '../src/hook.js'; import { deepAccess, deepSetValue, @@ -8,10 +8,11 @@ import { mergeDeep, prefixLog, } from '../src/utils.js'; +import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js'; const MODULE_NAME = '51Degrees'; export const LOG_PREFIX = `[${MODULE_NAME} RTD Submodule]:`; -const {logMessage, logWarn, logError} = prefixLog(LOG_PREFIX); +const { logMessage, logWarn, logError } = prefixLog(LOG_PREFIX); // ORTB device types const ORTB_DEVICE_TYPE = { @@ -100,7 +101,7 @@ export const extractConfig = (moduleConfig, reqBidsConfigObj) => { throw new Error(LOG_PREFIX + ' replace in configuration with a resource key obtained from https://configure.51degrees.com/HNZ75HT1'); } - return {resourceKey, onPremiseJSUrl}; + return { resourceKey, onPremiseJSUrl }; } /** @@ -126,7 +127,7 @@ export const get51DegreesJSURL = (pathData, win) => { ); deepSetNotEmptyValue(qs, '51D_ScreenPixelsHeight', _window?.screen?.height); deepSetNotEmptyValue(qs, '51D_ScreenPixelsWidth', _window?.screen?.width); - deepSetNotEmptyValue(qs, '51D_PixelRatio', _window?.devicePixelRatio); + deepSetNotEmptyValue(qs, '51D_PixelRatio', getDevicePixelRatio(_window)); const _qs = formatQS(qs); const _qsString = _qs ? `${queryPrefix}${_qs}` : ''; @@ -269,7 +270,7 @@ export const convert51DegreesDeviceToOrtb2 = (device) => { deepSetValue(ortb2Device, 'ext.fod.tpc', device.thirdpartycookiesenabled === 'True' ? 1 : 0); } - return {device: ortb2Device}; + return { device: ortb2Device }; } /** @@ -281,7 +282,7 @@ export const convert51DegreesDeviceToOrtb2 = (device) => { export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => { try { // Get the required config - const {resourceKey, onPremiseJSUrl} = extractConfig(moduleConfig, reqBidsConfigObj); + const { resourceKey, onPremiseJSUrl } = extractConfig(moduleConfig, reqBidsConfigObj); logMessage('Resource key: ', resourceKey); logMessage('On-premise JS URL: ', onPremiseJSUrl); @@ -295,7 +296,7 @@ export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, user getHighEntropyValues(['model', 'platform', 'platformVersion', 'fullVersionList']).then((hev) => { // Get 51Degrees JS URL, which is either cloud or on-premise - const scriptURL = get51DegreesJSURL({resourceKey, onPremiseJSUrl, hev}); + const scriptURL = get51DegreesJSURL({ resourceKey, onPremiseJSUrl, hev }); logMessage('URL of the script to be injected: ', scriptURL); // Inject 51Degrees script, get device data and merge it into the ORTB2 object @@ -312,7 +313,7 @@ export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, user logMessage('reqBidsConfigObj: ', reqBidsConfigObj); callback(); }); - }, document, {crossOrigin: 'anonymous'}); + }, document, { crossOrigin: 'anonymous' }); }); } catch (error) { // In case of an error, log it and continue diff --git a/modules/AsteriobidPbmAnalyticsAdapter.js b/modules/AsteriobidPbmAnalyticsAdapter.js index 3783f6c3765..fbd5a885b99 100644 --- a/modules/AsteriobidPbmAnalyticsAdapter.js +++ b/modules/AsteriobidPbmAnalyticsAdapter.js @@ -1,17 +1,17 @@ import { deepClone, generateUUID, getParameterByName, hasNonSerializableProperty, logError, parseUrl, logInfo } from '../src/utils.js'; -import {ajaxBuilder} from '../src/ajax.js'; +import { ajaxBuilder } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getStorageManager } from '../src/storageManager.js'; import { EVENTS } from '../src/constants.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; import { collectUtmTagData, trimAdUnit, trimBid, trimBidderRequest } from '../libraries/asteriobidUtils/asteriobidUtils.js'; /** * prebidmanagerAnalyticsAdapter.js - analytics adapter for prebidmanager */ -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: 'asteriobidpbm'}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: 'asteriobidpbm' }); const DEFAULT_EVENT_URL = 'https://endpt.prebidmanager.com/endpoint'; const analyticsType = 'endpoint'; const analyticsName = 'Asteriobid PBM Analytics'; @@ -26,7 +26,7 @@ var _bidRequestTimeout = 0; let flushInterval; var pmAnalyticsEnabled = false; -const {width: x, height: y} = getViewportSize(); +const { width: x, height: y } = getViewportSize(); var _pageView = { eventType: 'pageView', @@ -43,8 +43,8 @@ var _eventQueue = [ _pageView ]; -const prebidmanagerAnalytics = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType}), { - track({eventType, args}) { +const prebidmanagerAnalytics = Object.assign(adapter({ url: DEFAULT_EVENT_URL, analyticsType }), { + track({ eventType, args }) { handleEvent(eventType, args); } }); diff --git a/modules/_moduleMetadata.js b/modules/_moduleMetadata.js index bddb48a165c..d3e9fb34376 100644 --- a/modules/_moduleMetadata.js +++ b/modules/_moduleMetadata.js @@ -3,10 +3,10 @@ * Cfr. `gulp extract-metadata` */ -import {getGlobal} from '../src/prebidGlobal.js'; +import { getGlobal } from '../src/prebidGlobal.js'; import adapterManager from '../src/adapterManager.js'; -import {hook} from '../src/hook.js'; -import {GDPR_GVLIDS, VENDORLESS_GVLID} from '../src/consentHandler.js'; +import { hook } from '../src/hook.js'; +import { GDPR_GVLIDS, VENDORLESS_GVLID } from '../src/consentHandler.js'; import { MODULE_TYPE_ANALYTICS, MODULE_TYPE_BIDDER, @@ -85,7 +85,7 @@ function uidMetadata() { function analyticsMetadata() { return Object.fromEntries( Object.entries(adapterManager.analyticsRegistry) - .map(([provider, {gvlid, adapter}]) => { + .map(([provider, { gvlid, adapter }]) => { return [ provider, { diff --git a/modules/a1MediaBidAdapter.js b/modules/a1MediaBidAdapter.js index d640bbfe2d7..1df230dcfc1 100644 --- a/modules/a1MediaBidAdapter.js +++ b/modules/a1MediaBidAdapter.js @@ -89,10 +89,10 @@ export const spec = { adm: replaceAuctionPrice(bidItem.adm, bidItem.price), nurl: replaceAuctionPrice(bidItem.nurl, bidItem.price) })); - return {...seatbidItem, bid: parsedBid}; + return { ...seatbidItem, bid: parsedBid }; }); - const responseBody = {...serverResponse.body, seatbid: parsedSeatbid}; + const responseBody = { ...serverResponse.body, seatbid: parsedSeatbid }; const bids = converter.fromORTB({ response: responseBody, request: bidRequest.data, diff --git a/modules/a1MediaRtdProvider.js b/modules/a1MediaRtdProvider.js index 1fbe88ecfa0..682b6145996 100644 --- a/modules/a1MediaRtdProvider.js +++ b/modules/a1MediaRtdProvider.js @@ -14,7 +14,7 @@ const SCRIPT_URL = 'https://linkback.contentsfeed.com/src'; export const A1_SEG_KEY = '__a1tg'; export const A1_AUD_KEY = 'a1_gid'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME }); /** @type {RtdSubmodule} */ export const subModuleObj = { @@ -64,7 +64,7 @@ function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { ext: { segtax: 900 }, - segment: a1seg.split(',').map(x => ({id: x})) + segment: a1seg.split(',').map(x => ({ id: x })) }; const a1UserEid = { diff --git a/modules/a4gBidAdapter.js b/modules/a4gBidAdapter.js index 5bc3591e502..0d8d7514004 100644 --- a/modules/a4gBidAdapter.js +++ b/modules/a4gBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { _each } from '../src/utils.js'; const A4G_BIDDER_CODE = 'a4g'; diff --git a/modules/aaxBlockmeterRtdProvider.js b/modules/aaxBlockmeterRtdProvider.js index 0a72e4e36f1..f36cc2434d9 100644 --- a/modules/aaxBlockmeterRtdProvider.js +++ b/modules/aaxBlockmeterRtdProvider.js @@ -1,5 +1,5 @@ -import {isEmptyStr, isStr, logError, isFn, logWarn} from '../src/utils.js'; -import {submodule} from '../src/hook.js'; +import { isEmptyStr, isStr, logError, isFn, logWarn } from '../src/utils.js'; +import { submodule } from '../src/hook.js'; import { loadExternalScript } from '../src/adloader.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; diff --git a/modules/ablidaBidAdapter.js b/modules/ablidaBidAdapter.js index 3881d06f81a..9b61ad0d5b3 100644 --- a/modules/ablidaBidAdapter.js +++ b/modules/ablidaBidAdapter.js @@ -1,7 +1,7 @@ -import {triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; /** diff --git a/modules/aceexBidAdapter.js b/modules/aceexBidAdapter.js new file mode 100644 index 00000000000..71c3ac070dc --- /dev/null +++ b/modules/aceexBidAdapter.js @@ -0,0 +1,97 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { + buildRequestsBase, + buildPlacementProcessingFunction, +} from '../libraries/teqblazeUtils/bidderUtils.js'; + +import { deepAccess } from '../src/utils.js'; + +const BIDDER_CODE = 'aceex'; +const GVLID = 1387; +const AD_REQUEST_URL = 'https://bl-us.aceex.io/?secret_key=prebidjs'; + +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + placement.trafficType = placement.adFormat; + placement.publisherId = bid.params.publisherId; + placement.internalKey = bid.params.internalKey; +}; + +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); + +export const spec = { + code: BIDDER_CODE, + gvlid: GVLID, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: (bid) => { + return !!(bid.bidId && bid.params?.publisherId && bid.params?.trafficType); + }, + + buildRequests: (validBidRequests = [], bidderRequest) => { + const base = buildRequestsBase({ adUrl: AD_REQUEST_URL, validBidRequests, bidderRequest, placementProcessingFunction }); + + base.data.cat = deepAccess(bidderRequest, 'ortb2.cat'); + base.data.keywords = deepAccess(bidderRequest, 'ortb2.keywords'); + base.data.badv = deepAccess(bidderRequest, 'ortb2.badv'); + base.data.wseat = deepAccess(bidderRequest, 'ortb2.wseat'); + base.data.bseat = deepAccess(bidderRequest, 'ortb2.bseat'); + + return base; + }, + + interpretResponse: (serverResponse, bidRequest) => { + if (!serverResponse || !serverResponse.body || !Array.isArray(serverResponse.body.seatbid)) return []; + + const repackedBids = []; + + serverResponse.body.seatbid.forEach(seatbidItem => { + seatbidItem.bid.forEach((bid) => { + const originalPlacement = bidRequest.data.placements?.find(pl => pl.bidId === bid.id); + + const repackedBid = { + cpm: bid.price, + creativeId: bid.crid, + currency: 'USD', + dealId: bid.dealid, + height: bid.h, + width: bid.w, + mediaType: originalPlacement.adFormat, + netRevenue: true, + requestId: bid.id, + ttl: 1200, + meta: { + advertiserDomains: bid.adomain + }, + }; + + switch (originalPlacement.adFormat) { + case 'video': + repackedBid.vastXml = bid.adm; + break; + + case 'banner': + repackedBid.ad = bid.adm; + break; + + case 'native': + const nativeResponse = JSON.parse(bid.adm).native; + + const { assets, imptrackers, link } = nativeResponse; + repackedBid.native = { + ortb: { assets, imptrackers, link }, + }; + break; + + default: break; + }; + + repackedBids.push(repackedBid); + }) + }); + + return repackedBids; + }, +}; + +registerBidder(spec); diff --git a/modules/aceexBidAdapter.md b/modules/aceexBidAdapter.md new file mode 100644 index 00000000000..6efa00acd47 --- /dev/null +++ b/modules/aceexBidAdapter.md @@ -0,0 +1,67 @@ +# Overview + +``` +Module Name: Aceex Bidder Adapter +Module Type: Bidder Adapter +Maintainer: tech@aceex.io +``` + +# Description + +Module that connects Prebid.JS publishers to Aceex ad-exchange + +# Parameters + +| Name | Scope | Description | Example | +| :------------ | :------- | :------------------------ | :------------------- | +| `publisherId` | required | Publisher ID on platform | 219 | +| `trafficType` | required | Configures the mediaType that should be used. Values can be banner, native or video | "banner" | +| `internalKey` | required | Publisher hash on platform | "j1opp02hsma8119" | +| `bidfloor` | required | Bidfloor | 0.1 | + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'placementId_0', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'aceex', + params: { + publisherId: 219, + internalKey: 'j1opp02hsma8119', + trafficType: 'banner', + bidfloor: 0.2 + } + } + ] + }, + // Will return test vast video + { + code: 'placementId_0', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [ + { + bidder: 'aceex', + params: { + publisherId: 219, + internalKey: 'j1opp02hsma8119', + trafficType: 'video', + bidfloor: 1.1 + } + } + ] + } + ]; +``` diff --git a/modules/adWMGAnalyticsAdapter.js b/modules/adWMGAnalyticsAdapter.js index 73816422f04..f29ef639ab9 100644 --- a/modules/adWMGAnalyticsAdapter.js +++ b/modules/adWMGAnalyticsAdapter.js @@ -32,7 +32,7 @@ const bidWonObject = {}; let initOptions = {}; function postAjax(url, data) { - ajax(url, function () {}, data, {contentType: 'application/json', method: 'POST'}); + ajax(url, function () {}, data, { contentType: 'application/json', method: 'POST' }); } function handleInitSizes(adUnits) { diff --git a/modules/adWMGBidAdapter.js b/modules/adWMGBidAdapter.js index 8ae6d82ef61..d6ed1ff25b9 100644 --- a/modules/adWMGBidAdapter.js +++ b/modules/adWMGBidAdapter.js @@ -4,7 +4,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { BANNER } from '../src/mediaTypes.js'; import { parseUserAgentDetailed } from '../libraries/userAgentUtils/detailed.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const BIDDER_CODE = 'adWMG'; const ENDPOINT = 'https://hb.adwmg.com/hb'; diff --git a/modules/adagioAnalyticsAdapter.js b/modules/adagioAnalyticsAdapter.js index 1c3241ef19d..99661583743 100644 --- a/modules/adagioAnalyticsAdapter.js +++ b/modules/adagioAnalyticsAdapter.js @@ -158,7 +158,7 @@ function sendRequest(qp) { }, {}); const url = `${ENDPOINT}?${Object.keys(qp).map(key => `${key}=${enc(qp[key])}`).join('&')}`; - ajax(url, null, null, {method: 'GET'}); + ajax(url, null, null, { method: 'GET' }); }; /** diff --git a/modules/adagioRtdProvider.js b/modules/adagioRtdProvider.js index dfc6361234e..c3b1a881f98 100644 --- a/modules/adagioRtdProvider.js +++ b/modules/adagioRtdProvider.js @@ -31,7 +31,7 @@ import { _ADAGIO, getBestWindowForAdagio } from '../libraries/adagioUtils/adagio import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; -import {getGlobalVarName} from '../src/buildOptions.js'; +import { getGlobalVarName } from '../src/buildOptions.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule diff --git a/modules/adclusterBidAdapter.js b/modules/adclusterBidAdapter.js new file mode 100644 index 00000000000..b8b1f248582 --- /dev/null +++ b/modules/adclusterBidAdapter.js @@ -0,0 +1,183 @@ +import { registerBidder } from "../src/adapters/bidderFactory.js"; +import { BANNER, VIDEO } from "../src/mediaTypes.js"; + +const BIDDER_CODE = "adcluster"; +const ENDPOINT = "https://core.adcluster.com.tr/bid"; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid(bid) { + return !!bid?.params?.unitId; + }, + + buildRequests(validBidRequests, bidderRequest) { + const _auctionId = bidderRequest.auctionId || ""; + const payload = { + bidderCode: bidderRequest.bidderCode, + auctionId: _auctionId, + bidderRequestId: bidderRequest.bidderRequestId, + bids: validBidRequests.map((b) => buildImp(b)), + auctionStart: bidderRequest.auctionStart, + timeout: bidderRequest.timeout, + start: bidderRequest.start, + regs: { ext: {} }, + user: { ext: {} }, + source: { ext: {} }, + }; + + // privacy + if (bidderRequest?.gdprConsent) { + payload.regs = payload.regs || { ext: {} }; + payload.regs.ext = payload.regs.ext || {}; + payload.regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + payload.user.ext.consent = bidderRequest.gdprConsent.consentString || ""; + } + if (bidderRequest?.uspConsent) { + payload.regs = payload.regs || { ext: {} }; + payload.regs.ext.us_privacy = bidderRequest.uspConsent; + } + if (bidderRequest?.ortb2?.regs?.gpp) { + payload.regs = payload.regs || { ext: {} }; + payload.regs.ext.gpp = bidderRequest.ortb2.regs.gpp; + payload.regs.ext.gppSid = bidderRequest.ortb2.regs.gpp_sid; + } + if (validBidRequests[0]?.userIdAsEids) { + payload.user.ext.eids = validBidRequests[0].userIdAsEids; + } + if (validBidRequests[0]?.ortb2?.source?.ext?.schain) { + payload.source.ext.schain = validBidRequests[0].ortb2.source.ext.schain; + } + + return { + method: "POST", + url: ENDPOINT, + data: payload, + options: { contentType: "text/plain" }, + }; + }, + + interpretResponse(serverResponse) { + const body = serverResponse?.body; + if (!body || !Array.isArray(body)) return []; + const bids = []; + + body.forEach((b) => { + const mediaType = detectMediaType(b); + const bid = { + requestId: b.requestId, + cpm: b.cpm, + currency: b.currency, + width: b.width, + height: b.height, + creativeId: b.creativeId, + ttl: b.ttl, + netRevenue: b.netRevenue, + meta: { + advertiserDomains: b.meta?.advertiserDomains || [], + }, + mediaType, + }; + + if (mediaType === BANNER) { + bid.ad = b.ad; + } + if (mediaType === VIDEO) { + bid.vastUrl = b.ad; + } + bids.push(bid); + }); + + return bids; + }, +}; + +/* ---------- helpers ---------- */ + +function buildImp(bid) { + const _transactionId = bid.transactionId || ""; + const _adUnitId = bid.adUnitId || ""; + const _auctionId = bid.auctionId || ""; + const imp = { + params: { + unitId: bid.params.unitId, + }, + bidId: bid.bidId, + bidderRequestId: bid.bidderRequestId, + transactionId: _transactionId, + adUnitId: _adUnitId, + auctionId: _auctionId, + ext: { + floors: getFloorsAny(bid), + }, + }; + + if (bid.params && bid.params.previewMediaId) { + imp.params.previewMediaId = bid.params.previewMediaId; + } + + const mt = bid.mediaTypes || {}; + + // BANNER + if (mt.banner?.sizes?.length) { + imp.width = mt.banner.sizes[0] && mt.banner.sizes[0][0]; + imp.height = mt.banner.sizes[0] && mt.banner.sizes[0][1]; + } + if (mt.video) { + const v = mt.video; + const playerSize = toSizeArray(v.playerSize); + const [vw, vh] = playerSize?.[0] || []; + imp.width = vw; + imp.height = vh; + imp.video = { + minduration: v.minduration || 1, + maxduration: v.maxduration || 120, + ext: { + context: v.context || "instream", + floor: getFloors(bid, "video", playerSize?.[0]), + }, + }; + } + + return imp; +} + +function toSizeArray(s) { + if (!s) return null; + // playerSize can be [w,h] or [[w,h], [w2,h2]] + return Array.isArray(s[0]) ? s : [s]; +} + +function getFloors(bid, mediaType = "banner", size) { + try { + if (!bid.getFloor) return null; + // size can be [w,h] or '*' + const sz = Array.isArray(size) ? size : "*"; + const res = bid.getFloor({ mediaType, size: sz }); + return res && typeof res.floor === "number" ? res.floor : null; + } catch { + return null; + } +} + +function detectMediaType(bid) { + if (bid.mediaType === "video") return VIDEO; + else return BANNER; +} + +function getFloorsAny(bid) { + // Try to collect floors per type + const out = {}; + const mt = bid.mediaTypes || {}; + if (mt.banner) { + out.banner = getFloors(bid, "banner", "*"); + } + if (mt.video) { + const ps = toSizeArray(mt.video.playerSize); + out.video = getFloors(bid, "video", (ps && ps[0]) || "*"); + } + return out; +} + +registerBidder(spec); diff --git a/modules/adclusterBidAdapter.md b/modules/adclusterBidAdapter.md new file mode 100644 index 00000000000..59300e2c857 --- /dev/null +++ b/modules/adclusterBidAdapter.md @@ -0,0 +1,46 @@ +# Overview + +**Module Name**: Adcluster Bidder Adapter +**Module Type**: Bidder Adapter +**Maintainer**: dev@adcluster.com.tr + +# Description + +Prebid.js bidder adapter module for connecting to Adcluster. + +# Test Parameters + +``` +var adUnits = [ + { + code: 'adcluster-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [{ + bidder: 'adcluster', + params: { + unitId: '42d1f525-5792-47a6-846d-1825e53c97d6', + previewMediaId: "b4dbc48c-0b90-4628-bc55-f46322b89b63", + }, + }] + }, + { + code: 'adcluster-video', + mediaTypes: { + video: { + playerSize: [[640, 480]], + } + }, + bids: [{ + bidder: 'adcluster', + params: { + unitId: "37dd91b2-049d-4027-94b9-d63760fc10d3", + previewMediaId: "133b7dc9-bb6e-4ab2-8f95-b796cf19f27e", + }, + }] + } +]; +``` diff --git a/modules/addefendBidAdapter.js b/modules/addefendBidAdapter.js index 3ea95a6f63c..4393e3161e8 100644 --- a/modules/addefendBidAdapter.js +++ b/modules/addefendBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'addefend'; const GVLID = 539; diff --git a/modules/adfBidAdapter.js b/modules/adfBidAdapter.js index cdc48b1e28d..2653880233c 100644 --- a/modules/adfBidAdapter.js +++ b/modules/adfBidAdapter.js @@ -1,10 +1,10 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {deepAccess, deepClone, deepSetValue, getWinDimensions, parseSizesInput, setOnAny} from '../src/utils.js'; -import {Renderer} from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { deepAccess, deepClone, deepSetValue, getWinDimensions, parseSizesInput, setOnAny } from '../src/utils.js'; +import { Renderer } from '../src/Renderer.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const BIDDER_CODE = 'adf'; @@ -20,7 +20,7 @@ export const spec = { code: BIDDER_CODE, aliases: BIDDER_ALIAS, gvlid: GVLID, - supportedMediaTypes: [ NATIVE, BANNER, VIDEO ], + supportedMediaTypes: [NATIVE, BANNER, VIDEO], isBidRequestValid: (bid) => { const params = bid.params || {}; const { mid, inv, mname } = params; @@ -56,7 +56,7 @@ export const spec = { const pt = setOnAny(validBidRequests, 'params.pt') || setOnAny(validBidRequests, 'params.priceType') || 'net'; const test = setOnAny(validBidRequests, 'params.test'); const currency = getCurrencyFromBidderRequest(bidderRequest); - const cur = currency && [ currency ]; + const cur = currency && [currency]; const eids = setOnAny(validBidRequests, 'userIdAsEids'); const schain = setOnAny(validBidRequests, 'ortb2.source.ext.schain'); @@ -127,7 +127,7 @@ export const spec = { if (bannerParams && bannerParams.sizes) { const sizes = parseSizesInput(bannerParams.sizes); const format = sizes.map(size => { - const [ width, height ] = size.split('x'); + const [width, height] = size.split('x'); const w = parseInt(width, 10); const h = parseInt(height, 10); return { w, h }; @@ -223,7 +223,7 @@ export const spec = { } if (!bid.renderer && mediaType === VIDEO && deepAccess(bid, 'mediaTypes.video.context') === 'outstream') { - result.renderer = Renderer.install({id: bid.bidId, url: OUTSTREAM_RENDERER_URL, adUnitCode: bid.adUnitCode}); + result.renderer = Renderer.install({ id: bid.bidId, url: OUTSTREAM_RENDERER_URL, adUnitCode: bid.adUnitCode }); result.renderer.setRender(renderer); } diff --git a/modules/adgenerationBidAdapter.js b/modules/adgenerationBidAdapter.js index 779e40c8f9a..778cb697e80 100644 --- a/modules/adgenerationBidAdapter.js +++ b/modules/adgenerationBidAdapter.js @@ -61,9 +61,9 @@ export const spec = { * @return ServerRequest Info describing the request to the server. */ buildRequests: function (validBidRequests, bidderRequest) { - const ortbObj = converter.toORTB({bidRequests: validBidRequests, bidderRequest}); + const ortbObj = converter.toORTB({ bidRequests: validBidRequests, bidderRequest }); adgLogger.logInfo('ortbObj', ortbObj); - const {imp, ...rest} = ortbObj + const { imp, ...rest } = ortbObj const requests = imp.map((impObj) => { const customParams = impObj?.ext?.params; const id = getBidIdParameter('id', customParams); diff --git a/modules/adgridBidAdapter.ts b/modules/adgridBidAdapter.ts index e5ba2c8b672..6b5199817de 100644 --- a/modules/adgridBidAdapter.ts +++ b/modules/adgridBidAdapter.ts @@ -80,7 +80,7 @@ const buildRequests = ( bidRequests: BidRequest[], bidderRequest: ClientBidderRequest, ): AdapterRequest => { - const data:ORTBRequest = converter.toORTB({bidRequests, bidderRequest}) + const data:ORTBRequest = converter.toORTB({ bidRequests, bidderRequest }) const adapterRequest:AdapterRequest = { method: 'POST', url: REQUEST_URL, diff --git a/modules/adhashBidAdapter.js b/modules/adhashBidAdapter.js index a0846271ee5..a49345828ba 100644 --- a/modules/adhashBidAdapter.js +++ b/modules/adhashBidAdapter.js @@ -153,7 +153,7 @@ function brandSafety(badWords, maxScore) { export const spec = { code: ADHASH_BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: (bid) => { try { diff --git a/modules/adheseBidAdapter.js b/modules/adheseBidAdapter.js index 33b33ca998d..46b9039508b 100644 --- a/modules/adheseBidAdapter.js +++ b/modules/adheseBidAdapter.js @@ -88,7 +88,7 @@ export const spec = { syncurl += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); syncurl += '&consentString=' + encodeURIComponent(gdprConsent.consentString || ''); } - return [{type: 'iframe', url: syncurl}]; + return [{ type: 'iframe', url: syncurl }]; } } return []; diff --git a/modules/adipoloBidAdapter.js b/modules/adipoloBidAdapter.js index 51c2a97a1f0..4539c75574d 100644 --- a/modules/adipoloBidAdapter.js +++ b/modules/adipoloBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; import { getTimeZone } from '../libraries/timezone/timezone.js'; const BIDDER_CODE = 'adipolo'; diff --git a/modules/adkernelAdnAnalyticsAdapter.js b/modules/adkernelAdnAnalyticsAdapter.js index 725282ede6f..6e118f0a72c 100644 --- a/modules/adkernelAdnAnalyticsAdapter.js +++ b/modules/adkernelAdnAnalyticsAdapter.js @@ -1,18 +1,18 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {EVENTS} from '../src/constants.js'; +import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; import { logError, parseUrl, _each } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {config} from '../src/config.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { config } from '../src/config.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'adkernelAdn'; const GVLID = 14; const ANALYTICS_VERSION = '1.0.2'; const DEFAULT_QUEUE_TIMEOUT = 4000; const DEFAULT_HOST = 'tag.adkernel.com'; -const storageObj = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storageObj = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); const ADK_HB_EVENTS = { AUCTION_INIT: 'auctionInit', @@ -24,7 +24,7 @@ const ADK_HB_EVENTS = { }; function buildRequestTemplate(pubId) { - const {loc, ref} = getNavigationInfo(); + const { loc, ref } = getNavigationInfo(); return { ver: ANALYTICS_VERSION, @@ -43,9 +43,9 @@ function buildRequestTemplate(pubId) { } } -const analyticsAdapter = Object.assign(adapter({analyticsType: 'endpoint'}), +const analyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), { - track({eventType, args}) { + track({ eventType, args }) { if (!analyticsAdapter.context) { return; } @@ -115,7 +115,7 @@ export default analyticsAdapter; function sendAll() { const events = analyticsAdapter.context.queue.popAll(); if (events.length !== 0) { - const req = Object.assign({}, analyticsAdapter.context.requestTemplate, {hb_ev: events}); + const req = Object.assign({}, analyticsAdapter.context.requestTemplate, { hb_ev: events }); analyticsAdapter.ajaxCall(JSON.stringify(req)); } } @@ -158,7 +158,7 @@ function trackBidTimeout(args) { } function createHbEvent(adapter, event, tagid = undefined, value = 0, time = 0) { - const ev = {event: event}; + const ev = { event: event }; if (adapter) { ev.adapter = adapter } diff --git a/modules/adkernelAdnBidAdapter.js b/modules/adkernelAdnBidAdapter.js index d7053120ae6..1ab96f7145b 100644 --- a/modules/adkernelAdnBidAdapter.js +++ b/modules/adkernelAdnBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, deepSetValue, isArray, isNumber, isStr, logInfo, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {getBidFloor} from '../libraries/adkernelUtils/adkernelUtils.js' +import { deepAccess, deepSetValue, isArray, isNumber, isStr, logInfo, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { getBidFloor } from '../libraries/adkernelUtils/adkernelUtils.js' const DEFAULT_ADKERNEL_DSP_DOMAIN = 'tag.adkernel.com'; const DEFAULT_MIMES = ['video/mp4', 'video/webm', 'application/x-shockwave-flash', 'application/javascript']; @@ -59,7 +59,7 @@ function canonicalizeSizesArray(sizes) { } function buildRequestParams(tags, bidderRequest) { - const {gdprConsent, uspConsent, refererInfo, ortb2} = bidderRequest; + const { gdprConsent, uspConsent, refererInfo, ortb2 } = bidderRequest; const req = { id: bidderRequest.bidderRequestId, // TODO: root-level `tid` is not ORTB; is this intentional? @@ -213,7 +213,7 @@ function buildSyncs(serverResponses, propName, type) { return serverResponses.filter(rps => rps.body && rps.body[propName]) .map(rsp => rsp.body[propName]) .reduce((a, b) => a.concat(b), []) - .map(syncUrl => ({type: type, url: syncUrl})); + .map(syncUrl => ({ type: type, url: syncUrl })); } registerBidder(spec); diff --git a/modules/adkernelBidAdapter.js b/modules/adkernelBidAdapter.js index 81fa3501ea0..ed4b26da529 100644 --- a/modules/adkernelBidAdapter.js +++ b/modules/adkernelBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { _each, contains, @@ -16,11 +16,11 @@ import { parseGPTSingleSizeArrayToRtbSize, triggerPixel } from '../src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; -import {getBidFloor} from '../libraries/adkernelUtils/adkernelUtils.js' +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; +import { getBidFloor } from '../libraries/adkernelUtils/adkernelUtils.js' /** * In case you're AdKernel whitelable platform's client who needs branded adapter to @@ -65,51 +65,51 @@ export const spec = { code: 'adkernel', gvlid: GVLID, aliases: [ - {code: 'headbidding'}, - {code: 'adsolut'}, - {code: 'oftmediahb'}, - {code: 'audiencemedia'}, - {code: 'waardex_ak'}, - {code: 'roqoon'}, - {code: 'adbite'}, - {code: 'houseofpubs'}, - {code: 'torchad'}, - {code: 'stringads'}, - {code: 'bcm'}, - {code: 'engageadx'}, - {code: 'converge', gvlid: 248}, - {code: 'adomega'}, - {code: 'denakop'}, - {code: 'rtbanalytica'}, - {code: 'unibots'}, - {code: 'ergadx'}, - {code: 'turktelekom'}, - {code: 'motionspots'}, - {code: 'sonic_twist'}, - {code: 'displayioads'}, - {code: 'rtbdemand_com'}, - {code: 'bidbuddy'}, - {code: 'didnadisplay'}, - {code: 'qortex'}, - {code: 'adpluto'}, - {code: 'headbidder'}, - {code: 'digiad'}, - {code: 'monetix'}, - {code: 'hyperbrainz'}, - {code: 'voisetech'}, - {code: 'global_sun'}, - {code: 'rxnetwork'}, - {code: 'revbid'}, - {code: 'spinx', gvlid: 1308}, - {code: 'oppamedia'}, - {code: 'pixelpluses', gvlid: 1209}, - {code: 'urekamedia'}, - {code: 'smartyexchange'}, - {code: 'infinety'}, - {code: 'qohere'}, - {code: 'blutonic'}, - {code: 'appmonsta', gvlid: 1283}, - {code: 'intlscoop'} + { code: 'headbidding' }, + { code: 'adsolut' }, + { code: 'oftmediahb' }, + { code: 'audiencemedia' }, + { code: 'waardex_ak' }, + { code: 'roqoon' }, + { code: 'adbite' }, + { code: 'houseofpubs' }, + { code: 'torchad' }, + { code: 'stringads' }, + { code: 'bcm' }, + { code: 'engageadx' }, + { code: 'converge', gvlid: 248 }, + { code: 'adomega' }, + { code: 'denakop' }, + { code: 'rtbanalytica' }, + { code: 'unibots' }, + { code: 'ergadx' }, + { code: 'turktelekom' }, + { code: 'motionspots' }, + { code: 'sonic_twist' }, + { code: 'displayioads' }, + { code: 'rtbdemand_com' }, + { code: 'bidbuddy' }, + { code: 'didnadisplay' }, + { code: 'qortex' }, + { code: 'adpluto' }, + { code: 'headbidder' }, + { code: 'digiad' }, + { code: 'monetix' }, + { code: 'hyperbrainz' }, + { code: 'voisetech' }, + { code: 'global_sun' }, + { code: 'rxnetwork' }, + { code: 'revbid' }, + { code: 'spinx', gvlid: 1308 }, + { code: 'oppamedia' }, + { code: 'pixelpluses', gvlid: 1209 }, + { code: 'urekamedia' }, + { code: 'smartyexchange' }, + { code: 'infinety' }, + { code: 'qohere' }, + { code: 'blutonic' }, + { code: 'appmonsta', gvlid: 1283 }, + { code: 'intlscoop' } ], supportedMediaTypes: [BANNER, VIDEO, NATIVE], @@ -141,7 +141,7 @@ export const spec = { const requests = []; const schain = bidRequests[0]?.ortb2?.source?.ext?.schain; _each(impGroups, impGroup => { - const {host, zoneId, imps} = impGroup; + const { host, zoneId, imps } = impGroup; const request = buildRtbRequest(imps, bidderRequest, schain); requests.push({ method: 'POST', @@ -243,7 +243,7 @@ export const spec = { return serverResponses.filter(rsp => rsp.body && rsp.body.ext && rsp.body.ext.adk_usersync) .map(rsp => rsp.body.ext.adk_usersync) .reduce((a, b) => a.concat(b), []) - .map(({url, type}) => ({type: SYNC_TYPES[type], url: url})); + .map(({ url, type }) => ({ type: SYNC_TYPES[type], url: url })); }, /** @@ -270,9 +270,9 @@ function groupImpressionsByHostZone(bidRequests, refererInfo) { bidRequests.map(bidRequest => buildImps(bidRequest, secure)) .reduce((acc, curr, index) => { const bidRequest = bidRequests[index]; - const {zoneId, host} = bidRequest.params; + const { zoneId, host } = bidRequest.params; const key = `${host}_${zoneId}`; - acc[key] = acc[key] || {host: host, zoneId: zoneId, imps: []}; + acc[key] = acc[key] || { host: host, zoneId: zoneId, imps: [] }; acc[key].imps.push(...curr); return acc; }, {}) @@ -300,7 +300,7 @@ function buildImps(bidRequest, secure) { if (mediaTypes?.banner) { if (isMultiformat) { - typedImp = {...imp}; + typedImp = { ...imp }; typedImp.id = imp.id + MULTI_FORMAT_SUFFIX_BANNER; } else { typedImp = imp; @@ -319,7 +319,7 @@ function buildImps(bidRequest, secure) { if (mediaTypes?.video) { if (isMultiformat) { - typedImp = {...imp}; + typedImp = { ...imp }; typedImp.id = typedImp.id + MULTI_FORMAT_SUFFIX_VIDEO; } else { typedImp = imp; @@ -342,7 +342,7 @@ function buildImps(bidRequest, secure) { if (mediaTypes?.native) { if (isMultiformat) { - typedImp = {...imp}; + typedImp = { ...imp }; typedImp.id = typedImp.id + MULTI_FORMAT_SUFFIX_NATIVE; } else { typedImp = imp; @@ -419,7 +419,7 @@ function makeDevice(fpd) { if (getDNT()) { device.dnt = 1; } - return {device: device}; + return { device: device }; } /** @@ -429,12 +429,12 @@ function makeDevice(fpd) { * @returns {{site: Object}|{app: Object}} */ function makeSiteOrApp(bidderRequest, fpd) { - const {refererInfo} = bidderRequest; + const { refererInfo } = bidderRequest; const appConfig = config.getConfig('app'); if (isEmpty(appConfig)) { - return {site: createSite(refererInfo, fpd)} + return { site: createSite(refererInfo, fpd) } } else { - return {app: appConfig}; + return { app: appConfig }; } } @@ -445,7 +445,7 @@ function makeSiteOrApp(bidderRequest, fpd) { * @returns {{user: Object} | undefined} */ function makeUser(bidderRequest, fpd) { - const {gdprConsent} = bidderRequest; + const { gdprConsent } = bidderRequest; const user = fpd.user || {}; if (gdprConsent && gdprConsent.consentString !== undefined) { deepSetValue(user, 'ext.consent', gdprConsent.consentString); @@ -455,7 +455,7 @@ function makeUser(bidderRequest, fpd) { deepSetValue(user, 'ext.eids', eids); } if (!isEmpty(user)) { - return {user: user}; + return { user: user }; } } @@ -465,7 +465,7 @@ function makeUser(bidderRequest, fpd) { * @returns {{regs: Object} | undefined} */ function makeRegulations(bidderRequest) { - const {gdprConsent, uspConsent, gppConsent} = bidderRequest; + const { gdprConsent, uspConsent, gppConsent } = bidderRequest; const regs = {}; if (gdprConsent) { if (gdprConsent.gdprApplies !== undefined) { @@ -515,7 +515,7 @@ function makeBaseRequest(bidderRequest, imps, fpd) { * @param bidderRequest {BidderRequest} */ function makeSyncInfo(bidderRequest) { - const {bidderCode} = bidderRequest; + const { bidderCode } = bidderRequest; const syncMethod = getAllowedSyncMethod(bidderCode); if (syncMethod) { const res = {}; diff --git a/modules/adlooxAdServerVideo.js b/modules/adlooxAdServerVideo.js index d99d23743be..b7874b10997 100644 --- a/modules/adlooxAdServerVideo.js +++ b/modules/adlooxAdServerVideo.js @@ -174,22 +174,22 @@ function VASTWrapper(options, callback) { if (skipd) skip = durationToSeconds(skipd.trim()); const args = [ - [ 'client', '%%client%%' ], - [ 'platform_id', '%%platformid%%' ], - [ 'scriptname', 'adl_%%clientid%%' ], - [ 'tag_id', '%%tagid%%' ], - [ 'fwtype', 4 ], - [ 'vast', options.url ], - [ 'id11', 'video' ], - [ 'id12', '$ADLOOX_WEBSITE' ], - [ 'id18', (!skip || skip >= duration) ? 'fd' : 'od' ], - [ 'id19', 'na' ], - [ 'id20', 'na' ] + ['client', '%%client%%'], + ['platform_id', '%%platformid%%'], + ['scriptname', 'adl_%%clientid%%'], + ['tag_id', '%%tagid%%'], + ['fwtype', 4], + ['vast', options.url], + ['id11', 'video'], + ['id12', '$ADLOOX_WEBSITE'], + ['id18', (!skip || skip >= duration) ? 'fd' : 'od'], + ['id19', 'na'], + ['id20', 'na'] ]; - if (version && version !== 3) args.push([ 'version', version ]); - if (vpaid) args.push([ 'vpaid', 1 ]); - if (duration !== 15) args.push([ 'duration', duration ]); - if (skip) args.push([ 'skip', skip ]); + if (version && version !== 3) args.push(['version', version]); + if (vpaid) args.push(['vpaid', 1]); + if (duration !== 15) args.push(['duration', duration]); + if (skip) args.push(['skip', skip]); logInfo(MODULE, `processed VAST tag chain of depth ${chain.depth}, running callback`); diff --git a/modules/adlooxAnalyticsAdapter.js b/modules/adlooxAnalyticsAdapter.js index 99efaad3450..444e9ecf3c4 100644 --- a/modules/adlooxAnalyticsAdapter.js +++ b/modules/adlooxAnalyticsAdapter.js @@ -6,11 +6,11 @@ import adapterManager from '../src/adapterManager.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {AUCTION_COMPLETED} from '../src/auction.js'; -import {EVENTS} from '../src/constants.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { AUCTION_COMPLETED } from '../src/auction.js'; +import { EVENTS } from '../src/constants.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import { deepAccess, getUniqueIdentifierStr, @@ -26,7 +26,7 @@ import { mergeDeep, parseUrl } from '../src/utils.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE = 'adlooxAnalyticsAdapter'; @@ -159,9 +159,9 @@ analyticsAdapter.enableAnalytics = function(config) { .keys(config.options.params) .forEach(k => { if (!Array.isArray(config.options.params[k])) { - config.options.params[k] = [ config.options.params[k] ]; + config.options.params[k] = [config.options.params[k]]; } - config.options.params[k].forEach(v => analyticsAdapter.context.params.push([ k, v ])); + config.options.params[k].forEach(v => analyticsAdapter.context.params.push([k, v])); }); Object.keys(COMMAND_QUEUE).forEach(commandProcess); @@ -261,11 +261,11 @@ analyticsAdapter[`handle_${EVENTS.BID_WON}`] = function(bid) { logMessage(MODULE, `measuring '${bid.mediaType}' unit at '${bid.adUnitCode}'`); const params = analyticsAdapter.context.params.concat([ - [ 'tagid', '%%tagid%%' ], - [ 'platform', '%%platformid%%' ], - [ 'fwtype', 4 ], - [ 'targetelt', '%%targetelt%%' ], - [ 'creatype', '%%creatype%%' ] + ['tagid', '%%tagid%%'], + ['platform', '%%platformid%%'], + ['fwtype', 4], + ['targetelt', '%%targetelt%%'], + ['creatype', '%%creatype%%'] ]); loadExternalScript(analyticsAdapter.url(`${analyticsAdapter.context.js}#`, params, bid), MODULE_TYPE_ANALYTICS, 'adloox'); diff --git a/modules/adlooxRtdProvider.js b/modules/adlooxRtdProvider.js index 4fa954ded14..c991d776976 100644 --- a/modules/adlooxRtdProvider.js +++ b/modules/adlooxRtdProvider.js @@ -11,12 +11,12 @@ /* eslint prebid/validate-imports: "off" */ -import {auctionManager} from '../src/auctionManager.js'; -import {command as analyticsCommand, COMMAND} from './adlooxAnalyticsAdapter.js'; -import {submodule} from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { command as analyticsCommand, COMMAND } from './adlooxAnalyticsAdapter.js'; +import { submodule } from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import { _each, _map, @@ -35,7 +35,7 @@ import { parseUrl, safeJSONParse } from '../src/utils.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; const MODULE_NAME = 'adloox'; const MODULE = `${MODULE_NAME}RtdProvider`; @@ -83,7 +83,7 @@ function init(config, userConsent) { return false; } - config.params.thresholds = config.params.thresholds || [ 50, 60, 70, 80, 90 ]; + config.params.thresholds = config.params.thresholds || [50, 60, 70, 80, 90]; function analyticsConfigCallback(data) { config = mergeDeep(config.params, data); @@ -104,25 +104,27 @@ function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) { const adUnits = reqBidsConfigObj.adUnitCodes.map(code => adUnits0.find(unit => unit.code === code)); // buildUrl creates PHP style multi-parameters and includes undefined... (╯°□°)╯ ┻━┻ - const url = buildUrl(mergeDeep(parseUrl(`${API_ORIGIN}/q`), { search: { - 'v': 'pbjs-v' + '$prebid.version$', - 'c': config.params.clientid, - 'p': config.params.platformid, - 't': config.params.tagid, - 'imp': config.params.imps, - 'fc_ip': config.params.freqcap_ip, - 'fc_ipua': config.params.freqcap_ipua, - 'pn': (getRefererInfo().page || '').substr(0, 300).split(/[?#]/)[0], - 's': _map(adUnits, function(unit) { + const url = buildUrl(mergeDeep(parseUrl(`${API_ORIGIN}/q`), { + search: { + 'v': 'pbjs-v' + '$prebid.version$', + 'c': config.params.clientid, + 'p': config.params.platformid, + 't': config.params.tagid, + 'imp': config.params.imps, + 'fc_ip': config.params.freqcap_ip, + 'fc_ipua': config.params.freqcap_ipua, + 'pn': (getRefererInfo().page || '').substr(0, 300).split(/[?#]/)[0], + 's': _map(adUnits, function(unit) { // gptPreAuction runs *after* RTD so pbadslot may not be populated... (╯°□°)╯ ┻━┻ - const gpid = deepAccess(unit, 'ortb2Imp.ext.gpid') || + const gpid = deepAccess(unit, 'ortb2Imp.ext.gpid') || getGptSlotInfoForAdUnitCode(unit.code).gptSlot || unit.code; - const ref = [ gpid ]; - if (!config.params.slotinpath) ref.push(unit.code); - return ref.join('\t'); - }) - } })).replace(/\[\]|[^?&]+=undefined/g, '').replace(/([?&])&+/g, '$1'); + const ref = [gpid]; + if (!config.params.slotinpath) ref.push(unit.code); + return ref.join('\t'); + }) + } + })).replace(/\[\]|[^?&]+=undefined/g, '').replace(/([?&])&+/g, '$1'); ajax(url, function(responseText, q) { diff --git a/modules/admaruBidAdapter.js b/modules/admaruBidAdapter.js index f681a9a4191..364a13b55a1 100644 --- a/modules/admaruBidAdapter.js +++ b/modules/admaruBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const ADMARU_ENDPOINT = 'https://p1.admaru.net/AdCall'; const BIDDER_CODE = 'admaru'; diff --git a/modules/admaticBidAdapter.js b/modules/admaticBidAdapter.js index 4e75f7e583f..d83e7ed5ae9 100644 --- a/modules/admaticBidAdapter.js +++ b/modules/admaticBidAdapter.js @@ -28,6 +28,7 @@ export const spec = { { code: 'monetixads', gvlid: 1281 }, { code: 'netaddiction', gvlid: 1281 }, { code: 'adt', gvlid: 779 }, + { code: 'adrubi', gvlid: 779 }, { code: 'yobee', gvlid: 1281 } ], supportedMediaTypes: [BANNER, VIDEO, NATIVE], diff --git a/modules/admediaBidAdapter.js b/modules/admediaBidAdapter.js index e1cdbb86567..bf1aefe7521 100644 --- a/modules/admediaBidAdapter.js +++ b/modules/admediaBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/admixerBidAdapter.js b/modules/admixerBidAdapter.js index b0fdf042fa5..59d97fc71cf 100644 --- a/modules/admixerBidAdapter.js +++ b/modules/admixerBidAdapter.js @@ -1,18 +1,18 @@ -import {isStr, logError, isFn, deepAccess} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { isStr, logError, isFn, deepAccess } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'admixer'; const GVLID = 511; const ENDPOINT_URL = 'https://inv-nets.admixer.net/prebid.1.2.aspx'; const ALIASES = [ - {code: 'go2net', endpoint: 'https://ads.go2net.com.ua/prebid.1.2.aspx'}, + { code: 'go2net', endpoint: 'https://ads.go2net.com.ua/prebid.1.2.aspx' }, 'adblender', - {code: 'futureads', endpoint: 'https://ads.futureads.io/prebid.1.2.aspx'}, - {code: 'smn', endpoint: 'https://ads.smn.rs/prebid.1.2.aspx'}, - {code: 'admixeradx', endpoint: 'https://inv-nets.admixer.net/adxprebid.1.2.aspx'}, + { code: 'futureads', endpoint: 'https://ads.futureads.io/prebid.1.2.aspx' }, + { code: 'smn', endpoint: 'https://ads.smn.rs/prebid.1.2.aspx' }, + { code: 'admixeradx', endpoint: 'https://inv-nets.admixer.net/adxprebid.1.2.aspx' }, 'rtbstack', 'theads', ]; @@ -53,7 +53,8 @@ export const spec = { const payload = { imps: [], ortb2: bidderRequest.ortb2, - docReferrer: docRef}; + docReferrer: docRef + }; let endpointUrl; if (bidderRequest) { // checks if there is specified any endpointUrl in bidder config @@ -103,7 +104,7 @@ export const spec = { interpretResponse: function (serverResponse, bidRequest) { const bidResponses = []; try { - const {body: {ads = []} = {}} = serverResponse; + const { body: { ads = [] } = {} } = serverResponse; ads.forEach((ad) => bidResponses.push(ad)); } catch (e) { logError(e); @@ -112,13 +113,13 @@ export const spec = { }, getUserSyncs: function(syncOptions, serverResponses, gdprConsent) { const pixels = []; - serverResponses.forEach(({body: {cm = {}} = {}}) => { - const {pixels: img = [], iframes: frm = []} = cm; + serverResponses.forEach(({ body: { cm = {} } = {} }) => { + const { pixels: img = [], iframes: frm = [] } = cm; if (syncOptions.pixelEnabled) { - img.forEach((url) => pixels.push({type: 'image', url})); + img.forEach((url) => pixels.push({ type: 'image', url })); } if (syncOptions.iframeEnabled) { - frm.forEach((url) => pixels.push({type: 'iframe', url})); + frm.forEach((url) => pixels.push({ type: 'iframe', url })); } }); return pixels; diff --git a/modules/admixerIdSystem.js b/modules/admixerIdSystem.js index 04628d2356e..096d912426f 100644 --- a/modules/admixerIdSystem.js +++ b/modules/admixerIdSystem.js @@ -8,8 +8,8 @@ import { logError, logInfo } from '../src/utils.js' import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -19,7 +19,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; */ const NAME = 'admixerId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: NAME }); /** @type {Submodule} */ export const admixerIdSubmodule = { @@ -49,8 +49,8 @@ export const admixerIdSubmodule = { * @param {ConsentData} [consentData] * @returns {IdResponse|undefined} */ - getId(config, {gdpr: consentData} = {}) { - const {e, p, pid} = (config && config.params) || {}; + getId(config, { gdpr: consentData } = {}) { + const { e, p, pid } = (config && config.params) || {}; if (!pid || typeof pid !== 'string') { logError('admixerId submodule requires partner id to be defined'); return; @@ -90,7 +90,7 @@ export const admixerIdSubmodule = { function retrieveVisitorId(url, callback) { ajax(url, { success: response => { - const {setData: {visitorid} = {}} = JSON.parse(response || '{}'); + const { setData: { visitorid } = {} } = JSON.parse(response || '{}'); if (visitorid) { callback(visitorid); } else { diff --git a/modules/adnimationBidAdapter.js b/modules/adnimationBidAdapter.js new file mode 100644 index 00000000000..0c91d8e5f42 --- /dev/null +++ b/modules/adnimationBidAdapter.js @@ -0,0 +1,47 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { + isBidRequestValid, + onBidWon, + createUserSyncGetter, + createBuildRequestsFn, + createInterpretResponseFn +} from '../libraries/vidazooUtils/bidderUtils.js'; + +const DEFAULT_SUB_DOMAIN = 'exchange'; +const BIDDER_CODE = 'adnimation'; +const BIDDER_VERSION = '1.0.0'; +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); + +export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { + return `https://${subDomain}.adnimation.com`; +} + +function createUniqueRequestData(hashUrl, bid) { + const { auctionId, transactionId } = bid; + return { + auctionId, + transactionId + }; +} + +const buildRequests = createBuildRequestsFn(createDomain, createUniqueRequestData, storage, BIDDER_CODE, BIDDER_VERSION, false); +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.adnimation.com/api/sync/iframe', + imageSyncUrl: 'https://sync.adnimation.com/api/sync/image' +}); + +export const spec = { + code: BIDDER_CODE, + version: BIDDER_VERSION, + supportedMediaTypes: [BANNER, VIDEO], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs, + onBidWon, +}; + +registerBidder(spec); diff --git a/modules/adnimationBidAdapter.md b/modules/adnimationBidAdapter.md new file mode 100644 index 00000000000..df62967bd8d --- /dev/null +++ b/modules/adnimationBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +**Module Name:** Adnimation Bidder Adapter + +**Module Type:** Bidder Adapter + +**Maintainer:** prebid@adnimation.com + +# Description + +Module that connects to Adnimation's demand sources. + +# Test Parameters + +```js +var adUnits = [ + { + code: 'test-ad', + sizes: [[300, 250]], + bids: [ + { + bidder: 'adnimation', + params: { + cId: '562524b21b1c1f08117667f9', + pId: '59ac17c192832d0016683fe3', + bidFloor: 0.0001, + ext: { + param1: 'loremipsum', + param2: 'dolorsitamet' + } + } + } + ] + } +]; +``` diff --git a/modules/adnowBidAdapter.js b/modules/adnowBidAdapter.js index 23b65a783e2..d04ec1173f7 100644 --- a/modules/adnowBidAdapter.js +++ b/modules/adnowBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {deepAccess, parseQueryStringParameters, parseSizesInput} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { deepAccess, parseQueryStringParameters, parseSizesInput } from '../src/utils.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; @@ -30,7 +30,7 @@ const ENDPOINT = 'https://n.nnowa.com/a'; export const spec = { code: BIDDER_CODE, gvlid: GVLID, - supportedMediaTypes: [ NATIVE, BANNER ], + supportedMediaTypes: [NATIVE, BANNER], /** * @param {object} bid @@ -122,11 +122,11 @@ export const spec = { bid.requestId = bidObj.bidId; if (mediaType === BANNER) { - return [ this._getBannerBid(bid) ]; + return [this._getBannerBid(bid)]; } if (mediaType === NATIVE) { - return [ this._getNativeBid(bid) ]; + return [this._getNativeBid(bid)]; } return []; diff --git a/modules/adnuntiusAnalyticsAdapter.js b/modules/adnuntiusAnalyticsAdapter.js index 6de06332e3e..a2df85ad3f1 100644 --- a/modules/adnuntiusAnalyticsAdapter.js +++ b/modules/adnuntiusAnalyticsAdapter.js @@ -1,5 +1,5 @@ import { timestamp, logInfo } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; @@ -18,15 +18,15 @@ const cache = { auctions: {} }; -const adnAnalyticsAdapter = Object.assign(adapter({url: '', analyticsType: 'endpoint'}), { - track({eventType, args}) { +const adnAnalyticsAdapter = Object.assign(adapter({ url: '', analyticsType: 'endpoint' }), { + track({ eventType, args }) { const time = timestamp(); logInfo('ADN_EVENT:', [eventType, args]); switch (eventType) { case EVENTS.AUCTION_INIT: logInfo('ADN_AUCTION_INIT:', args); - cache.auctions[args.auctionId] = {bids: {}, bidAdUnits: {}}; + cache.auctions[args.auctionId] = { bids: {}, bidAdUnits: {} }; break; case EVENTS.BID_REQUESTED: logInfo('ADN_BID_REQUESTED:', args); @@ -169,7 +169,7 @@ adnAnalyticsAdapter.sendEvents = function() { return; } - ajax(initOptions.endPoint || URL, undefined, JSON.stringify(events), {method: 'POST'}); + ajax(initOptions.endPoint || URL, undefined, JSON.stringify(events), { method: 'POST' }); }; function getSentRequests() { @@ -202,7 +202,7 @@ function getSentRequests() { }); }); - return {gdpr: gdpr, auctionIds: auctionIds, sentRequests: sentRequests}; + return { gdpr: gdpr, auctionIds: auctionIds, sentRequests: sentRequests }; } function getResponses(gdpr, auctionIds) { @@ -278,7 +278,7 @@ function getGdprPos(gdpr, auction) { } if (gdprPos === gdpr.length) { - gdpr[gdprPos] = {gdprApplies: auction.gdprApplies, gdprConsent: auction.gdprConsent}; + gdpr[gdprPos] = { gdprApplies: auction.gdprApplies, gdprConsent: auction.gdprConsent }; } return gdprPos; diff --git a/modules/adnuntiusBidAdapter.js b/modules/adnuntiusBidAdapter.js index 4a4556cfb1e..8dd1ad55247 100644 --- a/modules/adnuntiusBidAdapter.js +++ b/modules/adnuntiusBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { convertObjectToArray, deepAccess, @@ -10,10 +10,10 @@ import { isEmpty, isStr } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {toLegacyResponse, toOrtbNativeRequest} from '../src/native.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { config } from '../src/config.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { toLegacyResponse, toOrtbNativeRequest } from '../src/native.js'; +import { getGlobal } from '../src/prebidGlobal.js'; const BIDDER_CODE = 'adnuntius'; const BIDDER_CODE_DEAL_ALIAS_BASE = 'adndeal'; @@ -358,7 +358,7 @@ export const spec = { networks[network].metaData = payloadRelatedData; } - const bidTargeting = {...bid.params.targeting || {}}; + const bidTargeting = { ...bid.params.targeting || {} }; targetingTool.mergeKvsFromOrtb(bidTargeting, bidderRequest); const mediaTypes = bid.mediaTypes || {}; const validMediaTypes = SUPPORTED_MEDIA_TYPES.filter(mt => { @@ -375,7 +375,7 @@ export const spec = { return; } const targetId = (bid.params.targetId || bid.bidId) + (isSingleFormat || mediaType === BANNER ? '' : ('-' + mediaType)); - const adUnit = {...bidTargeting, auId: bid.params.auId, targetId: targetId}; + const adUnit = { ...bidTargeting, auId: bid.params.auId, targetId: targetId }; if (mediaType === VIDEO) { adUnit.adType = 'VAST'; } else if (mediaType === NATIVE) { @@ -395,9 +395,9 @@ export const spec = { 'methods': [1] } ]; - adUnit.nativeRequest = {ortb: nativeOrtb} + adUnit.nativeRequest = { ortb: nativeOrtb } } else { - adUnit.nativeRequest = {ortb: mediaTypeData.ortb}; + adUnit.nativeRequest = { ortb: mediaTypeData.ortb }; } } const dealId = deepAccess(bid, 'params.dealId') || deepAccess(bid, 'params.inventory.pmp.deals'); diff --git a/modules/adplayerproVideoProvider.js b/modules/adplayerproVideoProvider.js index 56200ed95fa..af4729b13ce 100644 --- a/modules/adplayerproVideoProvider.js +++ b/modules/adplayerproVideoProvider.js @@ -26,9 +26,9 @@ import { SETUP_FAILED, VOLUME } from '../libraries/video/constants/events.js'; -import {AD_PLAYER_PRO_VENDOR} from '../libraries/video/constants/vendorCodes.js'; -import {getEventHandler} from '../libraries/video/shared/eventHandler.js'; -import {submodule} from '../src/hook.js'; +import { AD_PLAYER_PRO_VENDOR } from '../libraries/video/constants/vendorCodes.js'; +import { getEventHandler } from '../libraries/video/shared/eventHandler.js'; +import { submodule } from '../src/hook.js'; const setupFailMessage = 'Failed to instantiate the player'; @@ -350,14 +350,14 @@ export const utils = { } }, - getPlaybackMethod: function ({autoplay, mute}) { + getPlaybackMethod: function ({ autoplay, mute }) { if (autoplay) { return mute ? PLAYBACK_METHODS.AUTOPLAY_MUTED : PLAYBACK_METHODS.AUTOPLAY; } return PLAYBACK_METHODS.CLICK_TO_PLAY; }, - getPlcmt: function ({type, autoplay, muted, file}) { + getPlcmt: function ({ type, autoplay, muted, file }) { type = type || 'inStream'; if (!file) { // INTERSTITIAL: primary focus of the page and take up the majority of the viewport and cannot be scrolled out of view. diff --git a/modules/adpod.js b/modules/adpod.js index 3d82c91e42e..b123ac47e8d 100644 --- a/modules/adpod.js +++ b/modules/adpod.js @@ -30,13 +30,13 @@ import { getPriceByGranularity, getPriceGranularity } from '../src/auction.js'; -import {checkAdUnitSetup} from '../src/prebid.js'; -import {checkVideoBidSetup} from '../src/video.js'; -import {getHook, module, setupBeforeHookFnOnce} from '../src/hook.js'; -import {store} from '../src/videoCache.js'; -import {config} from '../src/config.js'; -import {ADPOD} from '../src/mediaTypes.js'; -import {auctionManager} from '../src/auctionManager.js'; +import { checkAdUnitSetup } from '../src/prebid.js'; +import { checkVideoBidSetup } from '../src/video.js'; +import { getHook, module, setupBeforeHookFnOnce } from '../src/hook.js'; +import { store } from '../src/videoCache.js'; +import { config } from '../src/config.js'; +import { ADPOD } from '../src/mediaTypes.js'; +import { auctionManager } from '../src/auctionManager.js'; import { TARGETING_KEYS } from '../src/constants.js'; const TARGETING_KEY_PB_CAT_DUR = 'hb_pb_cat_dur'; diff --git a/modules/adponeBidAdapter.js b/modules/adponeBidAdapter.js index 4e457b86f84..dbe8cc5fc39 100644 --- a/modules/adponeBidAdapter.js +++ b/modules/adponeBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {triggerPixel} from '../src/utils.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { triggerPixel } from '../src/utils.js'; const ADPONE_CODE = 'adpone'; const ADPONE_ENDPOINT = 'https://rtb.adpone.com/bid-request'; diff --git a/modules/adqueryBidAdapter.js b/modules/adqueryBidAdapter.js index 36a7eee206c..ccbee1e7fd7 100644 --- a/modules/adqueryBidAdapter.js +++ b/modules/adqueryBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { buildUrl, logInfo, @@ -328,7 +328,7 @@ function buildRequest(bid, bidderRequest, isVideo = false) { videoRequest.id = bid.bidId let currency = bid?.ortb2?.ext?.prebid?.adServerCurrency || "PLN"; - videoRequest.cur = [ currency ] + videoRequest.cur = [currency] let floorInfo; if (typeof bid.getFloor === 'function') { diff --git a/modules/adqueryIdSystem.js b/modules/adqueryIdSystem.js index 3f324506b45..f4c44d30ac1 100644 --- a/modules/adqueryIdSystem.js +++ b/modules/adqueryIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isFn, isPlainObject, isStr, logError, logInfo, logMessage} from '../src/utils.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { isFn, isPlainObject, isStr, logError, logInfo, logMessage } from '../src/utils.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -20,7 +20,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; const MODULE_NAME = 'qid'; const AU_GVLID = 902; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: 'qid'}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: 'qid' }); /** * Param or default. @@ -57,7 +57,7 @@ export const adqueryIdSubmodule = { * @returns {{qid:Object}} */ decode(value) { - return {qid: value} + return { qid: value } }, /** * performs action to obtain id and return a value in the callback's response argument @@ -121,9 +121,9 @@ export const adqueryIdSubmodule = { callback(); } }; - ajax(url + '?qid=' + qid, callbacks, undefined, {method: 'GET'}); + ajax(url + '?qid=' + qid, callbacks, undefined, { method: 'GET' }); }; - return {callback: resp}; + return { callback: resp }; }, eids: { 'qid': { diff --git a/modules/adrelevantisBidAdapter.js b/modules/adrelevantisBidAdapter.js index 7f2d850a23a..5b28d15a9f3 100644 --- a/modules/adrelevantisBidAdapter.js +++ b/modules/adrelevantisBidAdapter.js @@ -1,4 +1,4 @@ -import {Renderer} from '../src/Renderer.js'; +import { Renderer } from '../src/Renderer.js'; import { createTrackPixelHtml, deepAccess, @@ -12,15 +12,15 @@ import { logMessage, logWarn } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; -import {chunk} from '../libraries/chunk/chunk.js'; -import {transformSizes} from '../libraries/sizeUtils/tranformSize.js'; -import {hasUserInfo, hasAppDeviceInfo, hasAppId} from '../libraries/adrelevantisUtils/bidderUtils.js'; +import { getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; +import { chunk } from '../libraries/chunk/chunk.js'; +import { transformSizes } from '../libraries/sizeUtils/tranformSize.js'; +import { hasUserInfo, hasAppDeviceInfo, hasAppId } from '../libraries/adrelevantisUtils/bidderUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -83,7 +83,7 @@ export const spec = { const userObjBid = ((bidRequests) || []).find(hasUserInfo); let userObj; if (config.getConfig('coppa') === true) { - userObj = {'coppa': true}; + userObj = { 'coppa': true }; } if (userObjBid) { userObj = {}; @@ -166,7 +166,7 @@ export const spec = { * @param {*} serverResponse A successful response from the server. * @return {Bid[]} An array of bids which were nested inside the server. */ - interpretResponse: function(serverResponse, {bidderRequest}) { + interpretResponse: function(serverResponse, { bidderRequest }) { serverResponse = serverResponse.body; const bids = []; if (!serverResponse || serverResponse.error) { @@ -375,7 +375,8 @@ function newBid(serverBid, rtbBid, bidderRequest) { bid['native'].image = { url: nativeAd.main_img.url, height: nativeAd.main_img.height, - width: nativeAd.main_img.width}; + width: nativeAd.main_img.width + }; } if (nativeAd.icon) { bid['native'].icon = { @@ -419,7 +420,7 @@ function bidToTag(bid) { tag.prebid = true; tag.disable_psa = true; if (bid.params.position) { - tag.position = {'above': 1, 'below': 2}[bid.params.position] || 0; + tag.position = { 'above': 1, 'below': 2 }[bid.params.position] || 0; } else { const mediaTypePos = deepAccess(bid, `mediaTypes.banner.pos`) || deepAccess(bid, `mediaTypes.video.pos`); // only support unknown, atf, and btf values for position at this time @@ -459,7 +460,7 @@ function bidToTag(bid) { if (bid.nativeParams) { const nativeRequest = buildNativeRequest(bid.nativeParams); - tag[NATIVE] = {layouts: [nativeRequest]}; + tag[NATIVE] = { layouts: [nativeRequest] }; } } @@ -487,7 +488,7 @@ function bidToTag(bid) { } if (bid.renderer) { - tag.video = Object.assign({}, tag.video, {custom_renderer_present: true}); + tag.video = Object.assign({}, tag.video, { custom_renderer_present: true }); } if ( diff --git a/modules/adrinoBidAdapter.js b/modules/adrinoBidAdapter.js index bc3c929cd5a..f6a80e5b570 100644 --- a/modules/adrinoBidAdapter.js +++ b/modules/adrinoBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {triggerPixel} from '../src/utils.js'; -import {NATIVE, BANNER} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { triggerPixel } from '../src/utils.js'; +import { NATIVE, BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'adrino'; diff --git a/modules/adriverBidAdapter.js b/modules/adriverBidAdapter.js index 541d8e733eb..24b1fdc3c46 100644 --- a/modules/adriverBidAdapter.js +++ b/modules/adriverBidAdapter.js @@ -1,5 +1,5 @@ // ADRIVER BID ADAPTER for Prebid 1.13 -import {logInfo, getWindowLocation, _each, getBidIdParameter, isPlainObject} from '../src/utils.js'; +import { logInfo, getWindowLocation, _each, getBidIdParameter, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; @@ -7,7 +7,7 @@ const BIDDER_CODE = 'adriver'; const ADRIVER_BID_URL = 'https://pb.adriver.ru/cgi-bin/bid.cgi'; const TIME_TO_LIVE = 3000; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -73,7 +73,7 @@ export const spec = { } par = { 'id': bid.params.placementId, - 'ext': {'query': 'bn=15&custom=111=' + bid.bidId}, + 'ext': { 'query': 'bn=15&custom=111=' + bid.bidId }, 'banner': { 'w': width || undefined, 'h': height || undefined diff --git a/modules/adriverIdSystem.js b/modules/adriverIdSystem.js index 7e659e914b0..ad4c13c981e 100644 --- a/modules/adriverIdSystem.js +++ b/modules/adriverIdSystem.js @@ -8,8 +8,8 @@ import { logError, isPlainObject } from '../src/utils.js' import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -20,7 +20,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; const MODULE_NAME = 'adriverId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** @type {Submodule} */ export const adriverIdSubmodule = { @@ -81,10 +81,10 @@ export const adriverIdSubmodule = { } }; const newUrl = url + '&cid=' + (storage.getDataFromLocalStorage('adrcid') || storage.getCookie('adrcid')); - ajax(newUrl, callbacks, undefined, {method: 'GET'}); + ajax(newUrl, callbacks, undefined, { method: 'GET' }); } }; - return {callback: resp}; + return { callback: resp }; } }; diff --git a/modules/adspiritBidAdapter.js b/modules/adspiritBidAdapter.js index f474298ba82..d484e0c95b7 100644 --- a/modules/adspiritBidAdapter.js +++ b/modules/adspiritBidAdapter.js @@ -74,9 +74,9 @@ export const spec = { : [ { id: 1, required: 1, title: { len: 100 } }, { id: 2, required: 1, img: { type: 3, wmin: 1200, hmin: 627, mimes: ['image/png', 'image/gif', 'image/jpeg'] } }, - { id: 4, required: 1, data: {type: 2, len: 150} }, - { id: 3, required: 0, data: {type: 12, len: 50} }, - { id: 6, required: 0, data: {type: 1, len: 50} }, + { id: 4, required: 1, data: { type: 2, len: 150 } }, + { id: 3, required: 0, data: { type: 12, len: 50 } }, + { id: 6, required: 0, data: { type: 1, len: 50 } }, { id: 5, required: 0, img: { type: 1, wmin: 50, hmin: 50, mimes: ['image/png', 'image/gif', 'image/jpeg'] } } ] diff --git a/modules/adtargetBidAdapter.js b/modules/adtargetBidAdapter.js index 138f1b0e013..a40326d2e48 100644 --- a/modules/adtargetBidAdapter.js +++ b/modules/adtargetBidAdapter.js @@ -1,8 +1,8 @@ -import {_map, deepAccess, flatten, isArray, logError, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { _map, deepAccess, flatten, isArray, logError, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { chunk } from '../libraries/chunk/chunk.js'; import { createTag, getUserSyncsFn, isBidRequestValid, diff --git a/modules/adtelligentBidAdapter.js b/modules/adtelligentBidAdapter.js index 010d2b74409..589a251a333 100644 --- a/modules/adtelligentBidAdapter.js +++ b/modules/adtelligentBidAdapter.js @@ -1,9 +1,9 @@ -import {_map, deepAccess, flatten, isArray, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ADPOD, BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {Renderer} from '../src/Renderer.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { _map, deepAccess, flatten, isArray, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ADPOD, BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; +import { chunk } from '../libraries/chunk/chunk.js'; import { createTag, getUserSyncsFn, isBidRequestValid, @@ -30,7 +30,8 @@ const HOST_GETTERS = { ocm: () => 'ghb.cenarius.orangeclickmedia.com', '9dotsmedia': () => 'ghb.platform.audiodots.com', indicue: () => 'ghb.console.indicue.com', - stellormedia: () => 'ghb.ads.stellormedia.com'} + stellormedia: () => 'ghb.ads.stellormedia.com' +} const getUri = function (bidderCode) { const bidderWithoutSuffix = bidderCode.split('_')[0]; const getter = HOST_GETTERS[bidderWithoutSuffix] || HOST_GETTERS['default']; diff --git a/modules/adtelligentIdSystem.js b/modules/adtelligentIdSystem.js index 08d8a056dac..428633a6e4c 100644 --- a/modules/adtelligentIdSystem.js +++ b/modules/adtelligentIdSystem.js @@ -72,7 +72,7 @@ export const adtelligentIdModule = { * @param {ConsentData} [consentData] * @returns {IdResponse} */ - getId(config, {gdpr: consentData} = {}) { + getId(config, { gdpr: consentData } = {}) { const gdpr = consentData && consentData.gdprApplies ? 1 : 0; const gdprConsent = gdpr ? consentData.consentString : ''; const url = buildUrl({ diff --git a/modules/adtrueBidAdapter.js b/modules/adtrueBidAdapter.js index 2c4278b9fb8..b81dd579329 100644 --- a/modules/adtrueBidAdapter.js +++ b/modules/adtrueBidAdapter.js @@ -1,13 +1,13 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { logWarn, isArray, inIframe, isNumber, isStr, deepClone, deepSetValue, logError, deepAccess, isBoolean } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { getStorageManager } from '../src/storageManager.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'adtrue'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const ADTRUE_CURRENCY = 'USD'; const ENDPOINT_URL = 'https://hb.adtrue.com/prebid/auction'; const LOG_WARN_PREFIX = 'AdTrue: '; @@ -50,28 +50,28 @@ const VIDEO_CUSTOM_PARAMS = { }; const NATIVE_ASSETS = { - 'TITLE': {ID: 1, KEY: 'title', TYPE: 0}, - 'IMAGE': {ID: 2, KEY: 'image', TYPE: 0}, - 'ICON': {ID: 3, KEY: 'icon', TYPE: 0}, - 'SPONSOREDBY': {ID: 4, KEY: 'sponsoredBy', TYPE: 1}, // please note that type of SPONSORED is also 1 - 'BODY': {ID: 5, KEY: 'body', TYPE: 2}, // please note that type of DESC is also set to 2 - 'CLICKURL': {ID: 6, KEY: 'clickUrl', TYPE: 0}, - 'VIDEO': {ID: 7, KEY: 'video', TYPE: 0}, - 'EXT': {ID: 8, KEY: 'ext', TYPE: 0}, - 'DATA': {ID: 9, KEY: 'data', TYPE: 0}, - 'LOGO': {ID: 10, KEY: 'logo', TYPE: 0}, - 'SPONSORED': {ID: 11, KEY: 'sponsored', TYPE: 1}, // please note that type of SPONSOREDBY is also set to 1 - 'DESC': {ID: 12, KEY: 'data', TYPE: 2}, // please note that type of BODY is also set to 2 - 'RATING': {ID: 13, KEY: 'rating', TYPE: 3}, - 'LIKES': {ID: 14, KEY: 'likes', TYPE: 4}, - 'DOWNLOADS': {ID: 15, KEY: 'downloads', TYPE: 5}, - 'PRICE': {ID: 16, KEY: 'price', TYPE: 6}, - 'SALEPRICE': {ID: 17, KEY: 'saleprice', TYPE: 7}, - 'PHONE': {ID: 18, KEY: 'phone', TYPE: 8}, - 'ADDRESS': {ID: 19, KEY: 'address', TYPE: 9}, - 'DESC2': {ID: 20, KEY: 'desc2', TYPE: 10}, - 'DISPLAYURL': {ID: 21, KEY: 'displayurl', TYPE: 11}, - 'CTA': {ID: 22, KEY: 'cta', TYPE: 12} + 'TITLE': { ID: 1, KEY: 'title', TYPE: 0 }, + 'IMAGE': { ID: 2, KEY: 'image', TYPE: 0 }, + 'ICON': { ID: 3, KEY: 'icon', TYPE: 0 }, + 'SPONSOREDBY': { ID: 4, KEY: 'sponsoredBy', TYPE: 1 }, // please note that type of SPONSORED is also 1 + 'BODY': { ID: 5, KEY: 'body', TYPE: 2 }, // please note that type of DESC is also set to 2 + 'CLICKURL': { ID: 6, KEY: 'clickUrl', TYPE: 0 }, + 'VIDEO': { ID: 7, KEY: 'video', TYPE: 0 }, + 'EXT': { ID: 8, KEY: 'ext', TYPE: 0 }, + 'DATA': { ID: 9, KEY: 'data', TYPE: 0 }, + 'LOGO': { ID: 10, KEY: 'logo', TYPE: 0 }, + 'SPONSORED': { ID: 11, KEY: 'sponsored', TYPE: 1 }, // please note that type of SPONSOREDBY is also set to 1 + 'DESC': { ID: 12, KEY: 'data', TYPE: 2 }, // please note that type of BODY is also set to 2 + 'RATING': { ID: 13, KEY: 'rating', TYPE: 3 }, + 'LIKES': { ID: 14, KEY: 'likes', TYPE: 4 }, + 'DOWNLOADS': { ID: 15, KEY: 'downloads', TYPE: 5 }, + 'PRICE': { ID: 16, KEY: 'price', TYPE: 6 }, + 'SALEPRICE': { ID: 17, KEY: 'saleprice', TYPE: 7 }, + 'PHONE': { ID: 18, KEY: 'phone', TYPE: 8 }, + 'ADDRESS': { ID: 19, KEY: 'address', TYPE: 9 }, + 'DESC2': { ID: 20, KEY: 'desc2', TYPE: 10 }, + 'DISPLAYURL': { ID: 21, KEY: 'displayurl', TYPE: 11 }, + 'CTA': { ID: 22, KEY: 'cta', TYPE: 12 } }; function _getDomainFromURL(url) { @@ -299,7 +299,7 @@ function _createBannerRequest(bid) { format = []; sizes.forEach(function (size) { if (size.length > 1) { - format.push({w: size[0], h: size[1]}); + format.push({ w: size[0], h: size[1] }); } }); if (format.length > 0) { @@ -400,7 +400,7 @@ function _createImpressionObject(bid, conf) { } } else { // mediaTypes is not present, so this is a banner only impression - // this part of code is required for older testcases with no 'mediaTypes' to run succesfully. + // this part of code is required for older testcases with no 'mediaTypes' to run successfully. bannerObj = { pos: 0, w: bid.params.width, diff --git a/modules/aduptechBidAdapter.js b/modules/aduptechBidAdapter.js index fdc1249ded4..96a1b51b1ae 100644 --- a/modules/aduptechBidAdapter.js +++ b/modules/aduptechBidAdapter.js @@ -1,8 +1,8 @@ -import {deepClone, isArray, isBoolean, isEmpty, isFn, isPlainObject} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { deepClone, isArray, isBoolean, isEmpty, isFn, isPlainObject } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/advRedAnalyticsAdapter.js b/modules/advRedAnalyticsAdapter.js index 933d9bdc584..b9e0262a4ab 100644 --- a/modules/advRedAnalyticsAdapter.js +++ b/modules/advRedAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {generateUUID, logInfo} from '../src/utils.js' -import {ajaxBuilder} from '../src/ajax.js' +import { generateUUID, logInfo } from '../src/utils.js' +import { ajaxBuilder } from '../src/ajax.js' import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js' import adapterManager from '../src/adapterManager.js' -import {EVENTS} from '../src/constants.js' -import {getRefererInfo} from '../src/refererDetection.js'; +import { EVENTS } from '../src/constants.js' +import { getRefererInfo } from '../src/refererDetection.js'; /** * advRedAnalyticsAdapter.js - analytics adapter for AdvRed @@ -16,8 +16,8 @@ let initOptions let flushInterval let queue = [] -const advRedAnalytics = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType: 'endpoint'}), { - track({eventType, args}) { +const advRedAnalytics = Object.assign(adapter({ url: DEFAULT_EVENT_URL, analyticsType: 'endpoint' }), { + track({ eventType, args }) { handleEvent(eventType, args) } }) diff --git a/modules/advertisingBidAdapter.js b/modules/advertisingBidAdapter.js index 3fb035340c9..ac7bb125a7e 100644 --- a/modules/advertisingBidAdapter.js +++ b/modules/advertisingBidAdapter.js @@ -1,17 +1,17 @@ 'use strict'; -import {deepAccess, deepSetValue, isFn, isPlainObject, logWarn, mergeDeep} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { deepAccess, deepSetValue, isFn, isPlainObject, logWarn, mergeDeep } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import { config } from '../src/config.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; const BID_SCHEME = 'https://'; const BID_DOMAIN = 'technoratimedia.com'; const USER_SYNC_IFRAME_URL = 'https://ad-cdn.technoratimedia.com/html/usersync.html'; const USER_SYNC_PIXEL_URL = 'https://sync.technoratimedia.com/services'; -const VIDEO_PARAMS = [ 'minduration', 'maxduration', 'startdelay', 'placement', 'plcmt', 'linearity', 'mimes', 'protocols', 'api' ]; +const VIDEO_PARAMS = ['minduration', 'maxduration', 'startdelay', 'placement', 'plcmt', 'linearity', 'mimes', 'protocols', 'api']; const BLOCKED_AD_SIZES = [ '1x1', '1x2' @@ -23,7 +23,7 @@ export const spec = { { code: 'synacormedia' }, { code: 'imds' } ], - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], sizeMap: {}, isVideoBid: function(bid) { @@ -229,7 +229,7 @@ export const spec = { if (!serverResponse.body || typeof serverResponse.body !== 'object') { return; } - const {id, seatbid: seatbids} = serverResponse.body; + const { id, seatbid: seatbids } = serverResponse.body; const bids = []; if (id && seatbids) { seatbids.forEach(seatbid => { diff --git a/modules/adverxoBidAdapter.js b/modules/adverxoBidAdapter.js index a4e77ee9f30..0801fc021c1 100644 --- a/modules/adverxoBidAdapter.js +++ b/modules/adverxoBidAdapter.js @@ -1,10 +1,10 @@ import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; -import {ortbConverter as OrtbConverter} from '../libraries/ortbConverter/converter.js'; -import {Renderer} from '../src/Renderer.js'; -import {deepAccess, deepSetValue} from '../src/utils.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import { ortbConverter as OrtbConverter } from '../libraries/ortbConverter/converter.js'; +import { Renderer } from '../src/Renderer.js'; +import { deepAccess, deepSetValue } from '../src/utils.js'; +import { config } from '../src/config.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid @@ -19,10 +19,10 @@ import {config} from '../src/config.js'; const BIDDER_CODE = 'adverxo'; const ALIASES = [ - {code: 'adport', skipPbsAliasing: true}, - {code: 'bidsmind', skipPbsAliasing: true}, - {code: 'harrenmedia', skipPbsAliasing: true}, - {code: 'alchemyx', skipPbsAliasing: true} + { code: 'adport', skipPbsAliasing: true }, + { code: 'bidsmind', skipPbsAliasing: true }, + { code: 'harrenmedia', skipPbsAliasing: true }, + { code: 'alchemyx', skipPbsAliasing: true } ]; const AUCTION_URLS = { @@ -161,7 +161,7 @@ const videoUtils = { win.adxVideoRenderer.renderAd({ targetId: bid.adUnitCode, - adResponse: {content: bid.vastXml} + adResponse: { content: bid.vastXml } }); }); } diff --git a/modules/adxcgAnalyticsAdapter.js b/modules/adxcgAnalyticsAdapter.js index 34570a8dd71..04ccc64c43a 100644 --- a/modules/adxcgAnalyticsAdapter.js +++ b/modules/adxcgAnalyticsAdapter.js @@ -19,7 +19,7 @@ var adxcgAnalyticsAdapter = Object.assign(adapter( emptyUrl, analyticsType }), { - track ({eventType, args}) { + track ({ eventType, args }) { switch (eventType) { case EVENTS.AUCTION_INIT: adxcgAnalyticsAdapter.context.events.auctionInit = mapAuctionInit(args); @@ -40,7 +40,7 @@ var adxcgAnalyticsAdapter = Object.assign(adapter( adxcgAnalyticsAdapter.context.events.bidResponses.push(mapBidResponse(args, eventType)); break; case EVENTS.BID_WON: - const outData2 = {bidWons: mapBidWon(args)}; + const outData2 = { bidWons: mapBidWon(args) }; send(outData2); break; case EVENTS.AUCTION_END: diff --git a/modules/adxpremiumAnalyticsAdapter.js b/modules/adxpremiumAnalyticsAdapter.js index 5329336fd32..cdd8bbb91a2 100644 --- a/modules/adxpremiumAnalyticsAdapter.js +++ b/modules/adxpremiumAnalyticsAdapter.js @@ -1,5 +1,5 @@ -import {deepClone, logError, logInfo} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { deepClone, logError, logInfo } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; diff --git a/modules/adyoulikeBidAdapter.js b/modules/adyoulikeBidAdapter.js index 9054c197bbd..bb0f0b9a330 100644 --- a/modules/adyoulikeBidAdapter.js +++ b/modules/adyoulikeBidAdapter.js @@ -1,7 +1,7 @@ -import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { buildUrl, deepAccess, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; /** @@ -253,7 +253,7 @@ function getFloor(bidRequest, size, mediaType) { const bidFloors = bidRequest.getFloor({ currency: CURRENCY, mediaType, - size: [ size.width, size.height ] + size: [size.width, size.height] }); if (!isNaN(bidFloors?.floor) && (bidFloors?.currency === CURRENCY)) { diff --git a/modules/afpBidAdapter.js b/modules/afpBidAdapter.js index 3cb77a4eabc..a55bb007e5f 100644 --- a/modules/afpBidAdapter.js +++ b/modules/afpBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; export const IS_DEV = location.hostname === 'localhost' export const BIDDER_CODE = 'afp' @@ -66,12 +66,12 @@ const createRenderer = (bid, dataToCreatePlace) => { export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO], - isBidRequestValid({mediaTypes, params}) { + isBidRequestValid({ mediaTypes, params }) { if (typeof params !== 'object' || typeof mediaTypes !== 'object') { return false } - const {placeId, placeType, imageUrl, imageWidth, imageHeight} = params + const { placeId, placeType, imageUrl, imageWidth, imageHeight } = params const media = mediaTypes[mediaTypeByPlaceType[placeType]] if (placeId && media) { @@ -94,14 +94,16 @@ export const spec = { } return false }, - buildRequests(validBidRequests, {refererInfo, gdprConsent}) { + buildRequests(validBidRequests, { refererInfo, gdprConsent }) { const payload = { pageUrl: IS_DEV ? TEST_PAGE_URL : refererInfo.page, gdprConsent: gdprConsent, bidRequests: validBidRequests.map(validBidRequest => { - const {bidId, ortb2Imp, sizes, params: { - placeId, placeType, imageUrl, imageWidth, imageHeight - }} = validBidRequest + const { + bidId, ortb2Imp, sizes, params: { + placeId, placeType, imageUrl, imageWidth, imageHeight + } + } = validBidRequest bidRequestMap[bidId] = validBidRequest const bidRequest = { bidId, @@ -133,7 +135,7 @@ export const spec = { let bids = serverResponse.body && serverResponse.body.bids bids = Array.isArray(bids) ? bids : [] - return bids.map(({bidId, cpm, width, height, creativeId, currency, netRevenue, adSettings, placeSettings}, index) => { + return bids.map(({ bidId, cpm, width, height, creativeId, currency, netRevenue, adSettings, placeSettings }, index) => { const bid = { requestId: bidId, cpm, diff --git a/modules/agmaAnalyticsAdapter.js b/modules/agmaAnalyticsAdapter.js index cacdc5db976..ee7a7c1eb10 100644 --- a/modules/agmaAnalyticsAdapter.js +++ b/modules/agmaAnalyticsAdapter.js @@ -27,10 +27,10 @@ const pageViewId = generateUUID(); // Helper functions const getScreen = () => { try { - const {width: x, height: y} = getViewportSize(); + const { width: x, height: y } = getViewportSize(); return { x, y }; } catch (e) { - return {x: 0, y: 0}; + return { x: 0, y: 0 }; } }; diff --git a/modules/aidemBidAdapter.js b/modules/aidemBidAdapter.js index 8999de001b8..49c325d80ed 100644 --- a/modules/aidemBidAdapter.js +++ b/modules/aidemBidAdapter.js @@ -1,17 +1,17 @@ -import {deepAccess, deepClone, deepSetValue, getWinDimensions, isBoolean, isNumber, isStr, logError, logInfo} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {ajax} from '../src/ajax.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { deepAccess, deepClone, deepSetValue, getWinDimensions, isBoolean, isNumber, isStr, logError, logInfo } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { ajax } from '../src/ajax.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'aidem'; const BASE_URL = 'https://zero.aidemsrv.com'; const LOCAL_BASE_URL = 'http://127.0.0.1:8787'; const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO]; -const REQUIRED_VIDEO_PARAMS = [ 'mimes', 'protocols', 'context' ]; +const REQUIRED_VIDEO_PARAMS = ['mimes', 'protocols', 'context']; export const ERROR_CODES = { BID_SIZE_INVALID_FORMAT: 1, @@ -71,7 +71,7 @@ const converter = ortbConverter({ return imp; }, bidResponse(buildBidResponse, bid, context) { - const {bidRequest} = context; + const { bidRequest } = context; const bidResponse = buildBidResponse(bid, context); logInfo('Building bidResponse'); logInfo('bid', bid); @@ -262,7 +262,7 @@ export const spec = { buildRequests: function(bidRequests, bidderRequest) { logInfo('bidRequests: ', bidRequests); logInfo('bidderRequest: ', bidderRequest); - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); logInfo('request payload', data); return { method: 'POST', @@ -277,7 +277,7 @@ export const spec = { interpretResponse: function (serverResponse, request) { logInfo('serverResponse body: ', serverResponse.body); logInfo('request data: ', request.data); - const ortbBids = converter.fromORTB({response: serverResponse.body, request: request.data}).bids; + const ortbBids = converter.fromORTB({ response: serverResponse.body, request: request.data }).bids; logInfo('ortbBids: ', ortbBids); return ortbBids; }, diff --git a/modules/airgridRtdProvider.js b/modules/airgridRtdProvider.js index c547528a57e..fdcf57de873 100644 --- a/modules/airgridRtdProvider.js +++ b/modules/airgridRtdProvider.js @@ -5,11 +5,11 @@ * @module modules/airgridRtdProvider * @requires module:modules/realTimeData */ -import {submodule} from '../src/hook.js'; -import {deepAccess, deepSetValue, mergeDeep} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { deepAccess, deepSetValue, mergeDeep } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -81,7 +81,7 @@ export function setAudiencesAsBidderOrtb2(bidConfig, rtdConfig, audiences) { segtax: 540, }, name: 'airgrid', - segment: audiences.map((id) => ({id})) + segment: audiences.map((id) => ({ id })) } ] deepSetValue(agOrtb2, 'user.data', agUserData); diff --git a/modules/ajaBidAdapter.js b/modules/ajaBidAdapter.js index a00fd698932..75c3ec18141 100644 --- a/modules/ajaBidAdapter.js +++ b/modules/ajaBidAdapter.js @@ -1,7 +1,7 @@ -import {createTrackPixelHtml, logError, getBidIdParameter} from '../src/utils.js'; +import { createTrackPixelHtml, logError, getBidIdParameter } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/alkimiBidAdapter.js b/modules/alkimiBidAdapter.js index 8e77e2507b7..62beb22c521 100644 --- a/modules/alkimiBidAdapter.js +++ b/modules/alkimiBidAdapter.js @@ -1,16 +1,16 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepAccess, deepClone, generateUUID, replaceAuctionPrice} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {VIDEO, BANNER} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepAccess, deepClone, generateUUID, replaceAuctionPrice } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { VIDEO, BANNER } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'alkimi'; const GVLID = 1169; const USER_ID_KEY = 'alkimiUserID'; export const ENDPOINT = 'https://exchange.alkimi-onboarding.com/bid?prebid=true'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -85,7 +85,7 @@ export const spec = { let payload = { requestId: generateUUID(), - signRequest: {bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID}, + signRequest: { bids, randomUUID: alkimiConfig && alkimiConfig.randomUUID }, bidIds, referer: bidderRequest.refererInfo.page, signature: alkimiConfig && alkimiConfig.signature, @@ -148,7 +148,7 @@ export const spec = { return []; } - const {prebidResponse} = serverBody; + const { prebidResponse } = serverBody; if (!Array.isArray(prebidResponse)) { return []; } @@ -194,7 +194,7 @@ export const spec = { const urls = []; iframeList.forEach(url => { - urls.push({type: 'iframe', url}); + urls.push({ type: 'iframe', url }); }); return urls; @@ -204,7 +204,7 @@ export const spec = { }; function prepareSizes(sizes) { - return sizes ? sizes.map(size => ({width: size[0], height: size[1]})) : []; + return sizes ? sizes.map(size => ({ width: size[0], height: size[1] })) : []; } function prepareBidFloorSize(sizes) { diff --git a/modules/allegroBidAdapter.js b/modules/allegroBidAdapter.js index 3c42c9f1e60..55ef8dfee72 100644 --- a/modules/allegroBidAdapter.js +++ b/modules/allegroBidAdapter.js @@ -1,11 +1,11 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {config} from '../src/config.js'; -import {triggerPixel, logInfo, logError} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { config } from '../src/config.js'; +import { triggerPixel, logInfo, logError } from '../src/utils.js'; const BIDDER_CODE = 'allegro'; const BIDDER_URL = 'https://prebid.rtb.allegrogroup.com/v1/rtb/prebid/bid'; @@ -91,7 +91,7 @@ function moveExt(obj, newKey) { if (!obj || !obj.ext) { return; } - const extCopy = {...obj.ext}; + const extCopy = { ...obj.ext }; delete obj.ext; obj[newKey] = extCopy; } @@ -217,7 +217,7 @@ export const spec = { return { method: 'POST', url: url, - data: converter.toORTB({bidderRequest, bidRequests}), + data: converter.toORTB({ bidderRequest, bidRequests }), options: { contentType: 'text/plain' }, @@ -232,7 +232,7 @@ export const spec = { */ interpretResponse: function (response, request) { if (!response.body) return; - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; }, /** diff --git a/modules/allowActivities.js b/modules/allowActivities.js index 6af7eb36a62..1a9322b3659 100644 --- a/modules/allowActivities.js +++ b/modules/allowActivities.js @@ -1,5 +1,5 @@ -import {config} from '../src/config.js'; -import {registerActivityControl} from '../src/activities/rules.js'; +import { config } from '../src/config.js'; +import { registerActivityControl } from '../src/activities/rules.js'; const CFG_NAME = 'allowActivities'; const RULE_NAME = `${CFG_NAME} config`; @@ -34,7 +34,7 @@ export function updateRulesFromConfig(registerRule) { handles.set(priority, registerRule(activity, RULE_NAME, function (params) { for (const rule of rulesByActivity.get(activity).get(priority)) { if (!rule.condition || rule.condition(cleanParams(params))) { - return {allow: rule.allow, reason: rule} + return { allow: rule.allow, reason: rule } } } }, priority)); @@ -44,7 +44,7 @@ export function updateRulesFromConfig(registerRule) { function setupDefaultRule(activity) { if (!defaultRuleHandles.has(activity)) { defaultRuleHandles.set(activity, registerRule(activity, RULE_NAME, function () { - return {allow: false, reason: 'activity denied by default'} + return { allow: false, reason: 'activity denied by default' } }, Number.POSITIVE_INFINITY)) } } diff --git a/modules/ampliffyBidAdapter.js b/modules/ampliffyBidAdapter.js index 9eb2410e0f7..504becb106d 100644 --- a/modules/ampliffyBidAdapter.js +++ b/modules/ampliffyBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {logError, logInfo, triggerPixel} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { logError, logInfo, triggerPixel } from '../src/utils.js'; const BIDDER_CODE = 'ampliffy'; const DEFAULT_ENDPOINT = 'bidder.ampliffy.com'; @@ -347,9 +347,9 @@ function getSyncData(options, syncs) { if (syncs?.length) { for (const sync of syncs) { if (sync.type === 'syncImage' && options.pixelEnabled) { - ret.push({url: sync.url, type: 'image'}); + ret.push({ url: sync.url, type: 'image' }); } else if (sync.type === 'syncIframe' && options.iframeEnabled) { - ret.push({url: sync.url, type: 'iframe'}); + ret.push({ url: sync.url, type: 'iframe' }); } } } diff --git a/modules/amxBidAdapter.js b/modules/amxBidAdapter.js index ef89ecdd40f..78cd68c20a5 100644 --- a/modules/amxBidAdapter.js +++ b/modules/amxBidAdapter.js @@ -17,7 +17,7 @@ import { getStorageManager } from '../src/storageManager.js'; import { fetch } from '../src/ajax.js'; import { getGlobal } from '../src/prebidGlobal.js'; -import {getGlobalVarName} from '../src/buildOptions.js'; +import { getGlobalVarName } from '../src/buildOptions.js'; const BIDDER_CODE = 'amx'; const storage = getStorageManager({ bidderCode: BIDDER_CODE }); @@ -334,7 +334,8 @@ export const spec = { : { bidderRequestsCount: 0, bidderWinsCount: 0, - bidRequestsCount: 0 }; + bidRequestsCount: 0 + }; const payload = { a: generateUUID(), diff --git a/modules/amxIdSystem.js b/modules/amxIdSystem.js index 560ea3f0e3a..a4f85528426 100644 --- a/modules/amxIdSystem.js +++ b/modules/amxIdSystem.js @@ -5,16 +5,16 @@ * @module modules/amxIdSystem * @requires module:modules/userId */ -import {uspDataHandler} from '../src/adapterManager.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {deepAccess, logError} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; -import {domainOverrideToRootDomain} from '../libraries/domainOverrideToRootDomain/index.js'; +import { uspDataHandler } from '../src/adapterManager.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { deepAccess, logError } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { domainOverrideToRootDomain } from '../libraries/domainOverrideToRootDomain/index.js'; -import {getGlobalVarName} from '../src/buildOptions.js'; +import { getGlobalVarName } from '../src/buildOptions.js'; const NAME = 'amxId'; const GVL_ID = 737; @@ -22,9 +22,9 @@ const ID_KEY = NAME; const version = '2.0'; const SYNC_URL = 'https://id.a-mx.com/sync/'; const AJAX_TIMEOUT = 300; -const AJAX_OPTIONS = {method: 'GET', withCredentials: true, contentType: 'text/plain'}; +const AJAX_OPTIONS = { method: 'GET', withCredentials: true, contentType: 'text/plain' }; -export const storage = getStorageManager({moduleName: NAME, moduleType: MODULE_TYPE_UID}); +export const storage = getStorageManager({ moduleName: NAME, moduleType: MODULE_TYPE_UID }); const AMUID_KEY = '__amuidpb'; const getBidAdapterID = () => storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(AMUID_KEY) : null; diff --git a/modules/anonymisedRtdProvider.js b/modules/anonymisedRtdProvider.js index 98cf81edb2a..7de70668b2f 100644 --- a/modules/anonymisedRtdProvider.js +++ b/modules/anonymisedRtdProvider.js @@ -5,11 +5,11 @@ * @module modules/anonymisedRtdProvider * @requires module:modules/realTimeData */ -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isPlainObject, mergeDeep, logMessage, logWarn, logError} from '../src/utils.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; -import {loadExternalScript} from '../src/adloader.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { isPlainObject, mergeDeep, logMessage, logWarn, logError } from '../src/utils.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; +import { loadExternalScript } from '../src/adloader.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule */ @@ -60,7 +60,7 @@ export function createRtdProvider(moduleName) { logMessage(`${SUBMODULE_NAME}RtdProvider: Marketing Tag already loaded`); return; } - const tagConfig = config.params?.tagConfig ? {...config.params.tagConfig, idw_client_id: config.params.tagConfig.clientId} : {}; + const tagConfig = config.params?.tagConfig ? { ...config.params.tagConfig, idw_client_id: config.params.tagConfig.clientId } : {}; delete tagConfig.clientId; const tagUrl = config.params.tagUrl ? config.params.tagUrl : `${MARKETING_TAG_URL}?ref=prebid`; @@ -100,7 +100,7 @@ export function createRtdProvider(moduleName) { ext: { segtax: config.params.segtax }, - segment: segments.map(x => ({id: x})) + segment: segments.map(x => ({ id: x })) } logMessage(`${SUBMODULE_NAME}RtdProvider: user.data.segment: `, udSegment); diff --git a/modules/anyclipBidAdapter.js b/modules/anyclipBidAdapter.js index 8a5906ebc93..ce8cece011b 100644 --- a/modules/anyclipBidAdapter.js +++ b/modules/anyclipBidAdapter.js @@ -1,11 +1,11 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { buildRequests, getUserSyncs, interpretResponse, } from '../libraries/xeUtils/bidderUtils.js'; -import {deepAccess, getBidIdParameter, isArray, logError} from '../src/utils.js'; +import { deepAccess, getBidIdParameter, isArray, logError } from '../src/utils.js'; const BIDDER_CODE = 'anyclip'; const ENDPOINT = 'https://prebid.anyclip.com'; @@ -45,7 +45,7 @@ export const spec = { floor: req.floor }, })) - return {...builtRequests, data: JSON.stringify(updatedRequests)} + return { ...builtRequests, data: JSON.stringify(updatedRequests) } }, interpretResponse, getUserSyncs diff --git a/modules/apacdexBidAdapter.js b/modules/apacdexBidAdapter.js index cd433ef2c81..a4ec0d833cd 100644 --- a/modules/apacdexBidAdapter.js +++ b/modules/apacdexBidAdapter.js @@ -1,9 +1,9 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, isPlainObject, isArray, replaceAuctionPrice, isFn, logError, deepClone } from '../src/utils.js'; import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {parseDomain} from '../src/refererDetection.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { parseDomain } from '../src/refererDetection.js'; const BIDDER_CODE = 'apacdex'; const ENDPOINT = 'https://useast.quantumdex.io/auction/pbjs' const USERSYNC = 'https://sync.quantumdex.io/usersync/pbjs' diff --git a/modules/apesterBidAdapter.js b/modules/apesterBidAdapter.js new file mode 100644 index 00000000000..6d9cedb16f2 --- /dev/null +++ b/modules/apesterBidAdapter.js @@ -0,0 +1,49 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { + isBidRequestValid, + onBidWon, + createUserSyncGetter, + createBuildRequestsFn, + createInterpretResponseFn +} from '../libraries/vidazooUtils/bidderUtils.js'; + +const DEFAULT_SUB_DOMAIN = 'bidder'; +const BIDDER_CODE = 'apester'; +const BIDDER_VERSION = '1.0.0'; +const GVLID = 354; +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); + +export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { + return `https://${subDomain}.apester.com`; +} + +function createUniqueRequestData(hashUrl, bid) { + const { auctionId, transactionId } = bid; + return { + auctionId, + transactionId + }; +} + +const buildRequests = createBuildRequestsFn(createDomain, createUniqueRequestData, storage, BIDDER_CODE, BIDDER_VERSION, false); +const interpretResponse = createInterpretResponseFn(BIDDER_CODE, false); +const getUserSyncs = createUserSyncGetter({ + iframeSyncUrl: 'https://sync.apester.com/api/sync/iframe', + imageSyncUrl: 'https://sync.apester.com/api/sync/image' +}); + +export const spec = { + code: BIDDER_CODE, + version: BIDDER_VERSION, + supportedMediaTypes: [BANNER, VIDEO], + gvlid: GVLID, + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs, + onBidWon, +}; + +registerBidder(spec); diff --git a/modules/apesterBidAdapter.md b/modules/apesterBidAdapter.md new file mode 100644 index 00000000000..c43707d8a28 --- /dev/null +++ b/modules/apesterBidAdapter.md @@ -0,0 +1,36 @@ +# Overview + +**Module Name:** Apester Bidder Adapter + +**Module Type:** Bidder Adapter + +**Maintainer:** roni.katz@apester.com + +# Description + +Module that connects to Apester's demand sources. + +# Test Parameters + +```js +var adUnits = [ + { + code: 'test-ad', + sizes: [[300, 250]], + bids: [ + { + bidder: 'apester', + params: { + cId: '562524b21b1c1f08117667f9', + pId: '59ac17c192832d0016683fe3', + bidFloor: 0.0001, + ext: { + param1: 'loremipsum', + param2: 'dolorsitamet' + } + } + } + ] + } +]; +``` diff --git a/modules/appierAnalyticsAdapter.js b/modules/appierAnalyticsAdapter.js index 4773945d85c..c4d3d745542 100644 --- a/modules/appierAnalyticsAdapter.js +++ b/modules/appierAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {logError, logInfo, deepClone} from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { logError, logInfo, deepClone } from '../src/utils.js'; const analyticsType = 'endpoint'; @@ -43,7 +43,7 @@ export const parseAdUnitCode = function (bidResponse) { return bidResponse.adUnitCode.toLowerCase(); }; -export const appierAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, analyticsType}), { +export const appierAnalyticsAdapter = Object.assign(adapter({ DEFAULT_SERVER, analyticsType }), { cachedAuctions: {}, @@ -135,7 +135,7 @@ export const appierAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, ana message.adUnits[adUnitCode][bidder] = bidResponse; }, createBidMessage(auctionEndArgs, winningBids, timeoutBids) { - const {auctionId, timestamp, timeout, auctionEnd, adUnitCodes, bidsReceived, noBids} = auctionEndArgs; + const { auctionId, timestamp, timeout, auctionEnd, adUnitCodes, bidsReceived, noBids } = auctionEndArgs; const message = this.createCommonMessage(auctionId); message.auctionElapsed = (auctionEnd - timestamp); @@ -176,7 +176,7 @@ export const appierAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, ana const adUnitCode = parseAdUnitCode(bid); const bidder = parseBidderCode(bid); message.adUnits[adUnitCode] = message.adUnits[adUnitCode] || {}; - message.adUnits[adUnitCode][bidder] = {ad: bid.ad}; + message.adUnits[adUnitCode][bidder] = { ad: bid.ad }; }); return message; }, @@ -207,7 +207,7 @@ export const appierAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, ana handleBidWon(bidWonArgs) { this.sendEventMessage('imp', this.createImpressionMessage(bidWonArgs)); }, - track({eventType, args}) { + track({ eventType, args }) { if (analyticsOptions.sampled) { switch (eventType) { case BID_WON: diff --git a/modules/appnexusBidAdapter.js b/modules/appnexusBidAdapter.js index 0204c3e02b7..74d24afecf9 100644 --- a/modules/appnexusBidAdapter.js +++ b/modules/appnexusBidAdapter.js @@ -18,24 +18,24 @@ import { logWarn, mergeDeep } from '../src/utils.js'; -import {Renderer} from '../src/Renderer.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ADPOD, BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {bidderSettings} from '../src/bidderSettings.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js'; +import { Renderer } from '../src/Renderer.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ADPOD, BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { bidderSettings } from '../src/bidderSettings.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { APPNEXUS_CATEGORY_MAPPING } from '../libraries/categoryTranslationMapping/index.js'; import { convertKeywordStringToANMap, getANKewyordParamFromMaps, getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; -import {convertCamelToUnderscore, fill, appnexusAliases} from '../libraries/appnexusUtils/anUtils.js'; -import {convertTypes} from '../libraries/transformParamsUtils/convertTypes.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { convertCamelToUnderscore, fill, appnexusAliases } from '../libraries/appnexusUtils/anUtils.js'; +import { convertTypes } from '../libraries/transformParamsUtils/convertTypes.js'; +import { chunk } from '../libraries/chunk/chunk.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -99,7 +99,7 @@ const NATIVE_MAPPING = { const SOURCE = 'pbjs'; const MAX_IMPS_PER_REQUEST = 15; const GVLID = 32; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); // ORTB2 device types according to the OpenRTB specification const ORTB2_DEVICE_TYPE = { MOBILE_TABLET: 1, @@ -166,7 +166,7 @@ export const spec = { const segs = []; userObjBid.params.user[param].forEach(val => { if (isNumber(val)) { - segs.push({'id': val}); + segs.push({ 'id': val }); } else if (isPlainObject(val)) { segs.push(val); } @@ -367,7 +367,7 @@ export const spec = { bidRequests[0].userIdAsEids.forEach(eid => { if (!eid || !eid.uids || eid.uids.length < 1) { return; } eid.uids.forEach(uid => { - const tmp = {'source': eid.source, 'id': uid.id}; + const tmp = { 'source': eid.source, 'id': uid.id }; if (eid.source === 'adserver.org') { tmp.rti_partner = 'TDID'; } else if (eid.source === 'uidapi.com') { @@ -599,12 +599,13 @@ function newBid(serverBid, rtbBid, bidderRequest) { complete: 0, nodes: [{ bsid: rtbBid.buyer_member_id.toString() - }]}; + }] + }; return dchain; } if (rtbBid.buyer_member_id) { - bid.meta = Object.assign({}, bid.meta, {dchain: setupDChain(rtbBid)}); + bid.meta = Object.assign({}, bid.meta, { dchain: setupDChain(rtbBid) }); } if (rtbBid.brand_id) { diff --git a/modules/apstreamBidAdapter.js b/modules/apstreamBidAdapter.js index f432c85388f..68f391e106d 100644 --- a/modules/apstreamBidAdapter.js +++ b/modules/apstreamBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { generateUUID, deepAccess, createTrackPixelHtml } from '../src/utils.js'; import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; @@ -11,7 +11,7 @@ const CONSTANTS = { BIDDER_CODE: 'apstream', GVLID: 394 }; -const storage = getStorageManager({bidderCode: CONSTANTS.BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: CONSTANTS.BIDDER_CODE }); var dsuModule = (function() { 'use strict'; @@ -19,7 +19,7 @@ var dsuModule = (function() { var DSU_KEY = 'apr_dsu'; var DSU_VERSION_NUMBER = '1'; var SIGNATURE_SALT = 'YicAu6ZpNG'; - var DSU_CREATOR = {'USERREPORT': '1'}; + var DSU_CREATOR = { 'USERREPORT': '1' }; function stringToU8(str) { if (typeof TextEncoder === 'function') { diff --git a/modules/arcspanRtdProvider.js b/modules/arcspanRtdProvider.js index 451b521130d..c5c7621e369 100644 --- a/modules/arcspanRtdProvider.js +++ b/modules/arcspanRtdProvider.js @@ -1,6 +1,6 @@ import { submodule } from '../src/hook.js'; import { mergeDeep } from '../src/utils.js'; -import {loadExternalScript} from '../src/adloader.js'; +import { loadExternalScript } from '../src/adloader.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** diff --git a/modules/asoBidAdapter.js b/modules/asoBidAdapter.js index e1cde5bfd3f..08449d99b9b 100644 --- a/modules/asoBidAdapter.js +++ b/modules/asoBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, deepSetValue} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { deepAccess, deepSetValue } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'aso'; const DEFAULT_SERVER_URL = 'https://srv.aso1.net'; @@ -16,11 +16,11 @@ export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER, VIDEO, NATIVE], aliases: [ - {code: 'bcmint'}, - {code: 'bidgency'}, - {code: 'kuantyx'}, - {code: 'cordless'}, - {code: 'adklip'} + { code: 'bcmint' }, + { code: 'bidgency' }, + { code: 'kuantyx' }, + { code: 'cordless' }, + { code: 'adklip' } ], isBidRequestValid: bid => { @@ -31,7 +31,7 @@ export const spec = { const requests = []; bidRequests.forEach(bid => { - const data = converter.toORTB({bidRequests: [bid], bidderRequest}); + const data = converter.toORTB({ bidRequests: [bid], bidderRequest }); requests.push({ method: 'POST', url: getEndpoint(bid), @@ -48,7 +48,7 @@ export const spec = { interpretResponse: (response, request) => { if (response.body) { - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; } return []; }, diff --git a/modules/asteriobidAnalyticsAdapter.js b/modules/asteriobidAnalyticsAdapter.js index e4f7ee2a767..58ca7cec914 100644 --- a/modules/asteriobidAnalyticsAdapter.js +++ b/modules/asteriobidAnalyticsAdapter.js @@ -5,7 +5,7 @@ import adapterManager from '../src/adapterManager.js' import { getStorageManager } from '../src/storageManager.js' import { EVENTS } from '../src/constants.js' import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js' -import {getRefererInfo} from '../src/refererDetection.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import { collectUtmTagData, trimAdUnit, trimBid, trimBidderRequest } from '../libraries/asteriobidUtils/asteriobidUtils.js' /** diff --git a/modules/astraoneBidAdapter.js b/modules/astraoneBidAdapter.js index 216257fb7bc..5a8a7c1fd15 100644 --- a/modules/astraoneBidAdapter.js +++ b/modules/astraoneBidAdapter.js @@ -71,7 +71,7 @@ function wrapAd(bid, bidData) { parentDocument.style.height = "100%"; parentDocument.style.width = "100%"; } - var _html = "${encodeURIComponent(JSON.stringify({...bid, content: bidData.content}))}"; + var _html = "${encodeURIComponent(JSON.stringify({ ...bid, content: bidData.content }))}"; window._ao_ssp.registerInImage(JSON.parse(decodeURIComponent(_html))); diff --git a/modules/atsAnalyticsAdapter.js b/modules/atsAnalyticsAdapter.js index dcb43eb5f22..94e5264479e 100644 --- a/modules/atsAnalyticsAdapter.js +++ b/modules/atsAnalyticsAdapter.js @@ -2,13 +2,13 @@ import { logError, logInfo } from '../src/utils.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adaptermanager from '../src/adapterManager.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getGlobal } from '../src/prebidGlobal.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'atsAnalytics'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); /** * Analytics adapter for - https://liveramp.com @@ -275,12 +275,12 @@ export function parseBrowser() { function sendDataToAnalytic (events) { // send data to ats analytic endpoint try { - const dataToSend = {'Data': events}; + const dataToSend = { 'Data': events }; const strJSON = JSON.stringify(dataToSend); logInfo('ATS Analytics - tried to send analytics data!'); ajax(analyticsUrl, function () { logInfo('ATS Analytics - events sent successfully!'); - }, strJSON, {method: 'POST', contentType: 'application/json'}); + }, strJSON, { method: 'POST', contentType: 'application/json' }); } catch (err) { logError('ATS Analytics - request encounter an error: ', err); } @@ -306,7 +306,7 @@ function preflightRequest (events) { atsAnalyticsAdapter.setSamplingCookie(0); logInfo('ATS Analytics - Sampling Rate Request Error!'); } - }, undefined, {method: 'GET', crossOrigin: true}); + }, undefined, { method: 'GET', crossOrigin: true }); } const atsAnalyticsAdapter = Object.assign(adapter( @@ -314,7 +314,7 @@ const atsAnalyticsAdapter = Object.assign(adapter( analyticsType }), { - track({eventType, args}) { + track({ eventType, args }) { if (typeof args !== 'undefined') { atsAnalyticsAdapter.callHandler(eventType, args); } diff --git a/modules/automatadAnalyticsAdapter.js b/modules/automatadAnalyticsAdapter.js index e27061150c6..725dcacd7f2 100644 --- a/modules/automatadAnalyticsAdapter.js +++ b/modules/automatadAnalyticsAdapter.js @@ -14,7 +14,7 @@ import { getStorageManager } from '../src/storageManager.js' /** Prebid Event Handlers */ const ADAPTER_CODE = 'automatadAnalytics' -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: ADAPTER_CODE}) +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: ADAPTER_CODE }) const trialCountMilsMapping = [1500, 3000, 5000, 10000]; var isLoggingEnabled; var queuePointer = 0; var retryCount = 0; var timer = null; var __atmtdAnalyticsQueue = []; var qBeingUsed; var qTraversalComplete; @@ -197,14 +197,14 @@ const initializeQueue = () => { // ANALYTICS ADAPTER -const baseAdapter = adapter({analyticsType: 'bundle'}); +const baseAdapter = adapter({ analyticsType: 'bundle' }); const atmtdAdapter = Object.assign({}, baseAdapter, { disableAnalytics() { baseAdapter.disableAnalytics.apply(this, arguments); }, - track({eventType, args}) { + track({ eventType, args }) { const shouldNotPushToQueue = !self.qBeingUsed switch (eventType) { case EVENTS.AUCTION_INIT: diff --git a/modules/automatadBidAdapter.js b/modules/automatadBidAdapter.js index ad5ca6e128f..bf9f10eb816 100644 --- a/modules/automatadBidAdapter.js +++ b/modules/automatadBidAdapter.js @@ -1,7 +1,7 @@ -import {logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; +import { logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; const BIDDER = 'automatad' @@ -114,7 +114,7 @@ export const spec = { }, onTimeout: function(timeoutData) { const timeoutUrl = ENDPOINT_URL + '/timeout' - spec.ajaxCall(timeoutUrl, null, JSON.stringify(timeoutData), {method: 'POST', withCredentials: true}) + spec.ajaxCall(timeoutUrl, null, JSON.stringify(timeoutData), { method: 'POST', withCredentials: true }) }, onBidWon: function(bid) { if (!bid.nurl) { return } @@ -136,7 +136,7 @@ export const spec = { /\$\{AUCTION_ID\}/, bid.auctionId ) - spec.ajaxCall(winUrl, null, null, {method: 'GET', withCredentials: true}) + spec.ajaxCall(winUrl, null, null, { method: 'GET', withCredentials: true }) return true }, diff --git a/modules/axonixBidAdapter.js b/modules/axonixBidAdapter.js index c0b3f334c40..a621eedeabc 100644 --- a/modules/axonixBidAdapter.js +++ b/modules/axonixBidAdapter.js @@ -1,9 +1,9 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {deepAccess, isArray, isEmpty, logError, replaceAuctionPrice, triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {ajax} from '../src/ajax.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { deepAccess, isArray, isEmpty, logError, replaceAuctionPrice, triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { ajax } from '../src/ajax.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; const BIDDER_CODE = 'axonix'; diff --git a/modules/beachfrontBidAdapter.js b/modules/beachfrontBidAdapter.js index 3f627fe39e0..c1160567d80 100644 --- a/modules/beachfrontBidAdapter.js +++ b/modules/beachfrontBidAdapter.js @@ -7,9 +7,9 @@ import { logWarn, formatQS } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { getFirstSize, getOsVersion, getVideoSizes, getBannerSizes, isConnectedTV, getDoNotTrack, isMobile, isBannerBid, isVideoBid, getBannerBidFloor, getVideoBidFloor, getVideoTargetingParams, getTopWindowLocation } from '../libraries/advangUtils/index.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; @@ -39,7 +39,7 @@ let appId = ''; export const spec = { code: 'beachfront', - supportedMediaTypes: [ VIDEO, BANNER ], + supportedMediaTypes: [VIDEO, BANNER], gvlid: GVLID, isBidRequestValid(bid) { if (isVideoBid(bid)) { diff --git a/modules/bedigitechBidAdapter.js b/modules/bedigitechBidAdapter.js index 0baeea7470f..10fa08a2628 100644 --- a/modules/bedigitechBidAdapter.js +++ b/modules/bedigitechBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {_each, isArray} from '../src/utils.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { _each, isArray } from '../src/utils.js'; const BEDIGITECH_CODE = 'bedigitech'; const BEDIGITECH_ENDPOINT = 'https://bid.bedigitech.com/bid/pub_bid.php'; @@ -41,7 +41,7 @@ export const spec = { buildRequests: (bidRequests) => { return bidRequests.map(bid => { const url = BEDIGITECH_ENDPOINT; - const data = {'pid': bid.params.placementId}; + const data = { 'pid': bid.params.placementId }; return { method: BEDIGITECH_REQUEST_METHOD, url, diff --git a/modules/beopBidAdapter.js b/modules/beopBidAdapter.js index 16a67a42432..bf48da5aa40 100644 --- a/modules/beopBidAdapter.js +++ b/modules/beopBidAdapter.js @@ -27,7 +27,7 @@ const COOKIE_NAME = 'beopid'; const TCF_VENDOR_ID = 666; const validIdRegExp = /^[0-9a-fA-F]{24}$/ -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -192,12 +192,46 @@ function buildTrackingParams(data, info, value) { }; } +function normalizeAdUnitCode(adUnitCode) { + if (!adUnitCode || typeof adUnitCode !== 'string') return undefined; + + // Only normalize GPT auto-generated adUnitCodes (div-gpt-ad-*) + // For non-GPT codes, return original string unchanged to preserve case + if (!/^div-gpt-ad[-_]/i.test(adUnitCode)) { + return adUnitCode; + } + + // GPT handling: strip prefix and random suffix + let slot = adUnitCode; + slot = slot.replace(/^div-gpt-ad[-_]?/i, ''); + + /** + * Remove only long numeric suffixes (likely auto-generated IDs). + * Preserve short numeric suffixes as they may be meaningful slot indices. + * + * Examples removed: + * div-gpt-ad-article_top_123456 → article_top + * div-gpt-ad-sidebar-1678459238475 → sidebar + * + * Examples preserved: + * div-gpt-ad-topbanner-1 → topbanner-1 + * div-gpt-ad-topbanner-2 → topbanner-2 + */ + slot = slot.replace(/([_-])\d{6,}$/, ''); + + slot = slot.toLowerCase().trim(); + + if (slot.length < 3) return undefined; + + return slot; +} + function beOpRequestSlotsMaker(bid, bidderRequest) { const bannerSizes = deepAccess(bid, 'mediaTypes.banner.sizes'); const publisherCurrency = getCurrencyFromBidderRequest(bidderRequest) || getValue(bid.params, 'currency') || 'EUR'; let floor; if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: publisherCurrency, mediaType: 'banner', size: [1, 1]}); + const floorInfo = bid.getFloor({ currency: publisherCurrency, mediaType: 'banner', size: [1, 1] }); if (isPlainObject(floorInfo) && floorInfo.currency === publisherCurrency && !isNaN(parseFloat(floorInfo.floor))) { floor = parseFloat(floorInfo.floor); } @@ -211,7 +245,11 @@ function beOpRequestSlotsMaker(bid, bidderRequest) { nptnid: getValue(bid.params, 'networkPartnerId'), bid: getBidIdParameter('bidId', bid), brid: getBidIdParameter('bidderRequestId', bid), - name: getBidIdParameter('adUnitCode', bid), + name: deepAccess(bid, 'ortb2Imp.ext.gpid') || + deepAccess(bid, 'ortb2Imp.ext.data.adslot') || + deepAccess(bid, 'ortb2Imp.ext.data.adserver.adslot') || + bid.ortb2Imp?.tagid || + normalizeAdUnitCode(bid.adUnitCode), tid: bid.ortb2Imp?.ext?.tid || '', brc: getBidIdParameter('bidRequestsCount', bid), bdrc: getBidIdParameter('bidderRequestCount', bid), diff --git a/modules/betweenBidAdapter.js b/modules/betweenBidAdapter.js index d195f045b58..6bd1a413c18 100644 --- a/modules/betweenBidAdapter.js +++ b/modules/betweenBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {parseSizesInput} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { parseSizesInput } from '../src/utils.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -104,7 +104,7 @@ export const spec = { } } - requests.push({data: params}); + requests.push({ data: params }); }) return { method: 'POST', diff --git a/modules/bidResponseFilter/index.js b/modules/bidResponseFilter/index.js index 64026958bc6..8da669dd8f8 100644 --- a/modules/bidResponseFilter/index.js +++ b/modules/bidResponseFilter/index.js @@ -25,29 +25,33 @@ function init() { export function reset() { enabled = false; - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); + getHook('addBidResponse').getHooks({ hook: addBidResponseHook }).remove(); } export function addBidResponseHook(next, adUnitCode, bid, reject, index = auctionManager.index) { - const {bcat = [], badv = []} = index.getOrtb2(bid) || {}; + const { bcat = [], badv = [], cattax = 1 } = index.getOrtb2(bid) || {}; const bidRequest = index.getBidRequest(bid); const battr = bidRequest?.ortb2Imp[bid.mediaType]?.battr || index.getAdUnit(bid)?.ortb2Imp[bid.mediaType]?.battr || []; - const catConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.cat || {})}; - const advConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.adv || {})}; - const attrConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.attr || {})}; - const mediaTypesConfig = {enforce: true, blockUnknown: true, ...(moduleConfig?.mediaTypes || {})}; + const catConfig = { enforce: true, blockUnknown: true, ...(moduleConfig?.cat || {}) }; + const advConfig = { enforce: true, blockUnknown: true, ...(moduleConfig?.adv || {}) }; + const attrConfig = { enforce: true, blockUnknown: true, ...(moduleConfig?.attr || {}) }; + const mediaTypesConfig = { enforce: true, blockUnknown: true, ...(moduleConfig?.mediaTypes || {}) }; const { primaryCatId, secondaryCatIds = [], advertiserDomains = [], attr: metaAttr, mediaType: metaMediaType, + cattax: metaCattax = 1, } = bid.meta || {}; // checking if bid fulfills ortb2 fields rules - if ((catConfig.enforce && bcat.some(category => [primaryCatId, ...secondaryCatIds].includes(category))) || - (catConfig.blockUnknown && !primaryCatId)) { + const normalizedMetaCattax = Number(metaCattax); + const normalizedRequestCattax = Number(cattax); + const isCattaxMatch = normalizedMetaCattax === normalizedRequestCattax; + if ((catConfig.enforce && isCattaxMatch && bcat.some(category => [primaryCatId, ...secondaryCatIds].includes(category))) || + (catConfig.blockUnknown && (!isCattaxMatch || !primaryCatId))) { reject(BID_CATEGORY_REJECTION_REASON); } else if ((advConfig.enforce && badv.some(domain => advertiserDomains.includes(domain))) || (advConfig.blockUnknown && !advertiserDomains.length)) { diff --git a/modules/bidViewability.js b/modules/bidViewability.js index f1acc6096cc..2670f601a24 100644 --- a/modules/bidViewability.js +++ b/modules/bidViewability.js @@ -2,13 +2,13 @@ // GPT API is used to find when a bid is viewable, https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent // Does not work with other than GPT integration -import {config} from '../src/config.js'; +import { config } from '../src/config.js'; import * as events from '../src/events.js'; -import {EVENTS} from '../src/constants.js'; -import {isFn, logWarn, triggerPixel} from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import adapterManager, {gppDataHandler, uspDataHandler} from '../src/adapterManager.js'; -import {gdprParams} from '../libraries/dfpUtils/dfpUtils.js'; +import { EVENTS } from '../src/constants.js'; +import { isFn, logWarn, triggerPixel } from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import adapterManager, { gppDataHandler, uspDataHandler } from '../src/adapterManager.js'; +import { gdprParams } from '../libraries/dfpUtils/dfpUtils.js'; const MODULE_NAME = 'bidViewability'; const CONFIG_ENABLED = 'enabled'; diff --git a/modules/bidViewabilityIO.js b/modules/bidViewabilityIO.js index 195b551c85b..0e54d969b81 100644 --- a/modules/bidViewabilityIO.js +++ b/modules/bidViewabilityIO.js @@ -1,7 +1,7 @@ import { logMessage } from '../src/utils.js'; import { config } from '../src/config.js'; import * as events from '../src/events.js'; -import {EVENTS} from '../src/constants.js'; +import { EVENTS } from '../src/constants.js'; const MODULE_NAME = 'bidViewabilityIO'; const CONFIG_ENABLED = 'enabled'; @@ -77,7 +77,7 @@ export const init = () => { if (conf[MODULE_NAME][CONFIG_ENABLED] && CLIENT_SUPPORTS_IO) { // if the module is enabled and the browser supports Intersection Observer, // then listen to AD_RENDER_SUCCEEDED to setup IO's for supported mediaTypes - events.on(EVENTS.AD_RENDER_SUCCEEDED, ({doc, bid, id}) => { + events.on(EVENTS.AD_RENDER_SUCCEEDED, ({ doc, bid, id }) => { if (isSupportedMediaType(bid)) { const viewable = new IntersectionObserver(viewCallbackFactory(bid), getViewableOptions(bid)); const element = document.getElementById(bid.adUnitCode); diff --git a/modules/biddoBidAdapter.js b/modules/biddoBidAdapter.js index 6bfa0ac6ef8..fc9786a0b21 100644 --- a/modules/biddoBidAdapter.js +++ b/modules/biddoBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; import { buildBannerRequests, interpretBannerResponse } from '../libraries/biddoInvamiaUtils/index.js'; /** diff --git a/modules/bidglassBidAdapter.js b/modules/bidglassBidAdapter.js index 75999a8123e..2461145e6b3 100644 --- a/modules/bidglassBidAdapter.js +++ b/modules/bidglassBidAdapter.js @@ -1,5 +1,5 @@ -import {_each, isArray, deepClone, getUniqueIdentifierStr, getBidIdParameter} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { _each, isArray, deepClone, getUniqueIdentifierStr, getBidIdParameter } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/bidmaticBidAdapter.js b/modules/bidmaticBidAdapter.js index 4265b48428f..35d6e9b6078 100644 --- a/modules/bidmaticBidAdapter.js +++ b/modules/bidmaticBidAdapter.js @@ -4,7 +4,6 @@ import { cleanObj, deepAccess, flatten, - getWinDimensions, isArray, isNumber, logWarn, @@ -13,7 +12,7 @@ import { import { config } from '../src/config.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { chunk } from '../libraries/chunk/chunk.js'; -import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; +import { getPlacementPositionUtils } from "../libraries/placementPositionInfo/placementPositionInfo.js"; /** * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid @@ -21,10 +20,13 @@ import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingC * @typedef {import('../src/adapters/bidderFactory.js').BidderSpec} BidderSpec */ +const ADAPTER_VERSION = 'v1.0.0'; const URL = 'https://adapter.bidmatic.io/bdm/auction'; const BIDDER_CODE = 'bidmatic'; const SYNCS_DONE = new Set(); +const { getPlacementEnv, getPlacementInfo } = getPlacementPositionUtils() + /** @type {BidderSpec} */ export const spec = { code: BIDDER_CODE, @@ -144,6 +146,7 @@ export function parseResponseBody(serverResponse, adapterRequest) { export function remapBidRequest(bidRequests, adapterRequest) { const bidRequestBody = { + AdapterVersion: ADAPTER_VERSION, Domain: deepAccess(adapterRequest, 'refererInfo.page'), ...getPlacementEnv() }; @@ -237,50 +240,4 @@ export function createBid(bidResponse) { }; } -function getPlacementInfo(bidReq) { - const placementElementNode = document.getElementById(bidReq.adUnitCode); - try { - return cleanObj({ - AuctionsCount: bidReq.auctionsCount, - DistanceToView: getViewableDistance(placementElementNode) - }); - } catch (e) { - logWarn('Error while getting placement info', e); - return {}; - } -} - -/** - * @param element - */ -function getViewableDistance(element) { - if (!element) return 0; - const elementRect = getBoundingClientRect(element); - - if (!elementRect) { - return 0; - } - - const elementMiddle = elementRect.top + (elementRect.height / 2); - const viewportHeight = getWinDimensions().innerHeight - if (elementMiddle > window.scrollY + viewportHeight) { - // element is below the viewport - return Math.round(elementMiddle - (window.scrollY + viewportHeight)); - } - // element is above the viewport -> negative value - return Math.round(elementMiddle); -} - -function getPageHeight() { - return document.documentElement.scrollHeight || document.body.scrollHeight; -} - -function getPlacementEnv() { - return cleanObj({ - TimeFromNavigation: Math.floor(performance.now()), - TabActive: document.visibilityState === 'visible', - PageHeight: getPageHeight() - }) -} - registerBidder(spec); diff --git a/modules/bidtheatreBidAdapter.js b/modules/bidtheatreBidAdapter.js index a3e1a33c3b1..0216db6fbe9 100644 --- a/modules/bidtheatreBidAdapter.js +++ b/modules/bidtheatreBidAdapter.js @@ -11,7 +11,7 @@ const METHOD = 'POST'; const SUPPORTED_MEDIA_TYPES = [BANNER, VIDEO]; export const DEFAULT_CURRENCY = 'USD'; const BIDTHEATRE_COOKIE_NAME = '__kuid'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const converter = ortbConverter({ context: { @@ -68,7 +68,7 @@ export const spec = { return syncs; }, buildRequests(bidRequests, bidderRequest) { - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); const cookieValue = storage.getCookie(BIDTHEATRE_COOKIE_NAME); if (cookieValue) { @@ -104,7 +104,7 @@ export const spec = { }); const macroReplacedResponseBody = { ...response.body, seatbid: macroReplacedSeatbid }; - const bids = converter.fromORTB({response: macroReplacedResponseBody, request: request.data}).bids; + const bids = converter.fromORTB({ response: macroReplacedResponseBody, request: request.data }).bids; return bids; }, onTimeout: function(timeoutData) {}, diff --git a/modules/big-richmediaBidAdapter.js b/modules/big-richmediaBidAdapter.js index 858dad2ffde..654a4b92eb1 100644 --- a/modules/big-richmediaBidAdapter.js +++ b/modules/big-richmediaBidAdapter.js @@ -1,7 +1,7 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {spec as baseAdapter} from './appnexusBidAdapter.js'; // eslint-disable-line prebid/validate-imports +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { spec as baseAdapter } from './appnexusBidAdapter.js'; // eslint-disable-line prebid/validate-imports /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -16,7 +16,7 @@ export const spec = { version: '1.5.1', code: BIDDER_CODE, gvlid: baseAdapter.GVLID, // use base adapter gvlid - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], /** * Determines whether or not the given bid request is valid. diff --git a/modules/bitmediaBidAdapter.js b/modules/bitmediaBidAdapter.js index 7825c714f46..c3e4dcf0caf 100644 --- a/modules/bitmediaBidAdapter.js +++ b/modules/bitmediaBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { generateUUID, isEmpty, @@ -9,8 +9,8 @@ import { logInfo, triggerPixel } from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'bitmedia'; export const ENDPOINT_URL = 'https://cdn.bmcdn7.com/prebid/'; @@ -30,7 +30,7 @@ const ALLOWED_CURRENCIES = [ const DEFAULT_NET_REVENUE = true; const PREBID_VERSION = '$prebid.version$'; const ADAPTER_VERSION = '1.0'; -export const STORAGE = getStorageManager({bidderCode: BIDDER_CODE}); +export const STORAGE = getStorageManager({ bidderCode: BIDDER_CODE }); const USER_FINGERPRINT_KEY = 'bitmedia_fid'; const _handleOnBidWon = (endpoint) => { @@ -104,7 +104,7 @@ const CONVERTER = ortbConverter({ }); logInfo(BIDDER_CODE, 'Result imp objects for bidRequest', imps); // Should hasOwnProperty id. - return {id: bidRequest.bidId, imps}; + return { id: bidRequest.bidId, imps }; }, request(buildRequest, imps, bidderRequest, context) { @@ -174,8 +174,8 @@ const CONVERTER = ortbConverter({ const isBidRequestValid = (bid) => { logInfo(BIDDER_CODE, 'Validating bid request', bid); - const {banner} = bid.mediaTypes || {}; - const {adUnitID, currency} = bid.params || {}; + const { banner } = bid.mediaTypes || {}; + const { adUnitID, currency } = bid.params || {}; if (!banner || !Array.isArray(banner.sizes)) { logError(BIDDER_CODE, 'Invalid bid: missing or malformed banner sizes', banner); @@ -204,7 +204,7 @@ const isBidRequestValid = (bid) => { }; const buildRequests = (validBidRequests = [], bidderRequest = {}) => { - logInfo(BIDDER_CODE, 'Building OpenRTB request', {validBidRequests, bidderRequest}); + logInfo(BIDDER_CODE, 'Building OpenRTB request', { validBidRequests, bidderRequest }); const requests = validBidRequests.map(bidRequest => { const data = CONVERTER.toORTB({ bidRequests: [bidRequest], @@ -230,7 +230,7 @@ const buildRequests = (validBidRequests = [], bidderRequest = {}) => { }; const interpretResponse = (serverResponse, bidRequest) => { - logInfo(BIDDER_CODE, 'Interpreting server response', {serverResponse, bidRequest}); + logInfo(BIDDER_CODE, 'Interpreting server response', { serverResponse, bidRequest }); if (isEmpty(serverResponse.body)) { logInfo(BIDDER_CODE, 'Empty response'); @@ -249,7 +249,7 @@ const interpretResponse = (serverResponse, bidRequest) => { const onBidWon = (bid) => { const cpm = bid.adserverTargeting?.hb_pb || ''; - logInfo(BIDDER_CODE, `-----Bid won-----`, {bid, cpm: cpm}); + logInfo(BIDDER_CODE, `-----Bid won-----`, { bid, cpm: cpm }); _handleOnBidWon(bid.nurl); } diff --git a/modules/blueconicRtdProvider.js b/modules/blueconicRtdProvider.js index c09fc6ee34c..93a03db02f0 100644 --- a/modules/blueconicRtdProvider.js +++ b/modules/blueconicRtdProvider.js @@ -6,10 +6,10 @@ * @requires module:modules/realTimeData */ -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {mergeDeep, isPlainObject, logMessage, logError} from '../src/utils.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { mergeDeep, isPlainObject, logMessage, logError } from '../src/utils.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -20,7 +20,7 @@ const SUBMODULE_NAME = 'blueconic'; export const RTD_LOCAL_NAME = 'bcPrebidData'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME }); /** * Try parsing stringified array of data. @@ -61,7 +61,7 @@ export function getRealTimeData(reqBidsConfigObj, onDone, rtdConfig, userConsent if (!parsedData) { return; } - const userData = {name: 'blueconic', ...parsedData} + const userData = { name: 'blueconic', ...parsedData } logMessage('blueconicRtdProvider: userData: ', userData); const data = { ortb2: { diff --git a/modules/bmtmBidAdapter.js b/modules/bmtmBidAdapter.js index bc6a4415f97..36c5c3c89ca 100644 --- a/modules/bmtmBidAdapter.js +++ b/modules/bmtmBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { generateUUID, deepAccess, logWarn, deepSetValue, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; diff --git a/modules/bridBidAdapter.js b/modules/bridBidAdapter.js index afe9442e3ac..5e747301973 100644 --- a/modules/bridBidAdapter.js +++ b/modules/bridBidAdapter.js @@ -1,8 +1,8 @@ -import {_each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getAd, getSiteObj, getSyncResponse} from '../libraries/targetVideoUtils/bidderUtils.js' -import {GVLID, SOURCE, TIME_TO_LIVE, VIDEO_ENDPOINT_URL, VIDEO_PARAMS} from '../libraries/targetVideoUtils/constants.js'; +import { _each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize } from '../src/utils.js'; +import { VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getAd, getSiteObj, getSyncResponse } from '../libraries/targetVideoUtils/bidderUtils.js' +import { GVLID, SOURCE, TIME_TO_LIVE, VIDEO_ENDPOINT_URL, VIDEO_PARAMS } from '../libraries/targetVideoUtils/constants.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -56,7 +56,7 @@ export const spec = { const imp = { ext: { prebid: { - storedrequest: {'id': placementId} + storedrequest: { 'id': placementId } } } }; @@ -139,7 +139,7 @@ export const spec = { const requestId = bidRequest.bidId; const params = bidRequest.params; - const {ad, adUrl, vastUrl, vastXml} = getAd(bid); + const { ad, adUrl, vastUrl, vastXml } = getAd(bid); const bidResponse = { requestId, diff --git a/modules/bridgewellBidAdapter.js b/modules/bridgewellBidAdapter.js index 80e98dbd37e..9d85b5b43fe 100644 --- a/modules/bridgewellBidAdapter.js +++ b/modules/bridgewellBidAdapter.js @@ -1,6 +1,6 @@ -import {_each, deepSetValue, inIframe} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { _each, deepSetValue, inIframe } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; /** @@ -107,7 +107,7 @@ export const spec = { const mediaType = bid.mediaTypes?.banner ? BANNER : (bid.mediaTypes?.native ? NATIVE : '*'); const sizes = bid.mediaTypes?.banner?.sizes || bid.sizes || []; const size = sizes.length === 1 ? sizes[0] : '*'; - floorInfo = bid.getFloor({currency: 'USD', mediaType: mediaType, size: size}) || {}; + floorInfo = bid.getFloor({ currency: 'USD', mediaType: mediaType, size: size }) || {}; } adUnit.floor = floorInfo.floor; adUnit.currency = floorInfo.currency; diff --git a/modules/browsiBidAdapter.js b/modules/browsiBidAdapter.js index cb256254e12..b3049739323 100644 --- a/modules/browsiBidAdapter.js +++ b/modules/browsiBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {logError, logInfo, isArray, isStr} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { VIDEO } from '../src/mediaTypes.js'; +import { logError, logInfo, isArray, isStr } from '../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid @@ -29,8 +29,8 @@ export const spec = { if (!bid.params) { return false; } - const {pubId, tagId} = bid.params - const {mediaTypes} = bid; + const { pubId, tagId } = bid.params + const { mediaTypes } = bid; return !!(validateBrowsiIds(pubId, tagId) && mediaTypes?.[VIDEO]); }, /** @@ -41,9 +41,9 @@ export const spec = { */ buildRequests: function (validBidRequests, bidderRequest) { const requests = []; - const {refererInfo, bidderRequestId, gdprConsent, uspConsent} = bidderRequest; + const { refererInfo, bidderRequestId, gdprConsent, uspConsent } = bidderRequest; validBidRequests.forEach(bidRequest => { - const {bidId, adUnitCode, auctionId, ortb2Imp, params} = bidRequest; + const { bidId, adUnitCode, auctionId, ortb2Imp, params } = bidRequest; const schain = bidRequest?.ortb2?.source?.ext?.schain; const video = getVideoMediaType(bidRequest); @@ -141,7 +141,7 @@ export const spec = { onTimeout(timeoutData) { logInfo(`${BIDDER_CODE} bidder timed out`, timeoutData); }, - onBidderError: function ({error}) { + onBidderError: function ({ error }) { logError(`${BIDDER_CODE} bidder error`, error); } } diff --git a/modules/buzzoolaBidAdapter.js b/modules/buzzoolaBidAdapter.js index fd3d3cd189e..f118b8c3e16 100644 --- a/modules/buzzoolaBidAdapter.js +++ b/modules/buzzoolaBidAdapter.js @@ -1,8 +1,8 @@ import { deepAccess, deepClone } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {OUTSTREAM} from '../src/video.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { OUTSTREAM } from '../src/video.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; /** @@ -55,7 +55,7 @@ export const spec = { * @param {ServerResponse} serverResponse A successful response from the server. * @return {Bid[]} An array of bids which were nested inside the server. */ - interpretResponse: function ({body}, {data}) { + interpretResponse: function ({ body }, { data }) { const requestBids = {}; let response; diff --git a/modules/byDataAnalyticsAdapter.js b/modules/byDataAnalyticsAdapter.js index 265dcf2115b..57c85e290e6 100644 --- a/modules/byDataAnalyticsAdapter.js +++ b/modules/byDataAnalyticsAdapter.js @@ -5,10 +5,10 @@ import enc from 'crypto-js/enc-utf8'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS, BID_STATUS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getStorageManager } from '../src/storageManager.js'; import { auctionManager } from '../src/auctionManager.js'; import { ajax } from '../src/ajax.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; import { getOsBrowserInfo } from '../libraries/userAgentUtils/detailed.js'; import { getTimeZone } from '../libraries/timezone/timezone.js'; @@ -21,7 +21,7 @@ const analyticsType = 'endpoint' const isBydata = isKeyInUrl('bydata_debug') const adunitsMap = {} const MODULE_CODE = 'bydata'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); let initOptions = {} var payload = {} @@ -208,7 +208,7 @@ ascAdapter.getVisitorData = function (data = {}) { return signedToken; } function detectWidth() { - const {width: viewportWidth} = getViewportSize(); + const { width: viewportWidth } = getViewportSize(); const windowDimensions = getWinDimensions(); return windowDimensions.screen.width || (windowDimensions.innerWidth && windowDimensions.document.documentElement.clientWidth) ? Math.min(windowDimensions.innerWidth, windowDimensions.document.documentElement.clientWidth) : viewportWidth; } diff --git a/modules/cadent_aperture_mxBidAdapter.js b/modules/cadent_aperture_mxBidAdapter.js index f13bda26102..741bc0db16b 100644 --- a/modules/cadent_aperture_mxBidAdapter.js +++ b/modules/cadent_aperture_mxBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { _each, deepAccess, getBidIdParameter, @@ -9,10 +9,10 @@ import { logError, logWarn } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {parseDomain} from '../src/refererDetection.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { parseDomain } from '../src/refererDetection.js'; const BIDDER_CODE = 'cadent_aperture_mx'; const ENDPOINT = 'hb.emxdgt.com'; @@ -20,10 +20,10 @@ const RENDERER_URL = 'https://js.brealtime.com/outstream/1.30.0/bundle.js'; const ADAPTER_VERSION = '1.5.1'; const DEFAULT_CUR = 'USD'; const ALIASES = [ - { code: 'emx_digital'}, - { code: 'cadent'}, - { code: 'emxdigital'}, - { code: 'cadentaperturemx'}, + { code: 'emx_digital' }, + { code: 'cadent' }, + { code: 'emxdigital' }, + { code: 'cadentaperturemx' }, ]; const EIDS_SUPPORTED = [ @@ -87,7 +87,8 @@ export const cadentAdapter = { h: screen.height, w: screen.width, devicetype: cadentAdapter.isMobile() ? 1 : cadentAdapter.isConnectedTV() ? 3 : 2, - language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage)}; + language: (navigator.language || navigator.browserLanguage || navigator.userLanguage || navigator.systemLanguage) + }; }, cleanProtocols: (video) => { if (video.protocols && video.protocols.includes(7)) { @@ -173,7 +174,7 @@ export const cadentAdapter = { getGpp: (bidRequest, cadentData) => { if (bidRequest.gppConsent) { - const {gppString: gpp, applicableSections: gppSid} = bidRequest.gppConsent; + const { gppString: gpp, applicableSections: gppSid } = bidRequest.gppConsent; if (cadentData.regs) { cadentData.regs.gpp = gpp; cadentData.regs.gpp_sid = gppSid; @@ -315,7 +316,7 @@ export const spec = { cadentData.user.ext.eids = eids; } else { cadentData.user = { - ext: {eids} + ext: { eids } }; } } diff --git a/modules/categoryTranslation.js b/modules/categoryTranslation.js index a0ef902412e..a1925921e44 100644 --- a/modules/categoryTranslation.js +++ b/modules/categoryTranslation.js @@ -11,13 +11,13 @@ * If publisher has not defined translation file than prebid will use default prebid translation file provided here //cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json */ -import {config} from '../src/config.js'; -import {hook, setupBeforeHookFnOnce, ready} from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import {logError, timestamp} from '../src/utils.js'; -import {addBidResponse} from '../src/auction.js'; -import {getCoreStorageManager} from '../src/storageManager.js'; -import {timedBidResponseHook} from '../src/utils/perfMetrics.js'; +import { config } from '../src/config.js'; +import { hook, setupBeforeHookFnOnce, ready } from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { logError, timestamp } from '../src/utils.js'; +import { addBidResponse } from '../src/auction.js'; +import { getCoreStorageManager } from '../src/storageManager.js'; +import { timedBidResponseHook } from '../src/utils/perfMetrics.js'; export const storage = getCoreStorageManager('categoryTranslation'); const DEFAULT_TRANSLATION_FILE_URL = 'https://cdn.jsdelivr.net/gh/prebid/category-mapping-file@1/freewheel-mapping.json'; diff --git a/modules/ccxBidAdapter.js b/modules/ccxBidAdapter.js index 14268185027..3bb60cef907 100644 --- a/modules/ccxBidAdapter.js +++ b/modules/ccxBidAdapter.js @@ -1,9 +1,9 @@ -import {_each, deepAccess, isArray, isEmpty, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { _each, deepAccess, isArray, isEmpty, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'ccx' -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const BID_URL = 'https://delivery.clickonometrics.pl/ortb/prebid/bid' const SUPPORTED_VIDEO_PROTOCOLS = [2, 3, 5, 6] const SUPPORTED_VIDEO_MIMES = ['video/mp4', 'video/x-flv'] @@ -72,13 +72,13 @@ function _buildBid (bid, bidderRequest) { const sizes = deepAccess(bid, 'mediaTypes.banner.sizes') || deepAccess(bid, 'mediaTypes.video.playerSize') || deepAccess(bid, 'sizes') if (deepAccess(bid, 'mediaTypes.banner') || deepAccess(bid, 'mediaType') === 'banner' || (!deepAccess(bid, 'mediaTypes.video') && !deepAccess(bid, 'mediaType'))) { - placement.banner = {'format': []} + placement.banner = { 'format': [] } if (isArray(sizes[0])) { _each(sizes, function (size) { - placement.banner.format.push({'w': size[0], 'h': size[1]}) + placement.banner.format.push({ 'w': size[0], 'h': size[1] }) }) } else { - placement.banner.format.push({'w': sizes[0], 'h': sizes[1]}) + placement.banner.format.push({ 'w': sizes[0], 'h': sizes[1] }) } } else if (deepAccess(bid, 'mediaTypes.video') || deepAccess(bid, 'mediaType') === 'video') { placement.video = {} @@ -102,7 +102,7 @@ function _buildBid (bid, bidderRequest) { } } - placement.ext = {'pid': bid.params.placementId} + placement.ext = { 'pid': bid.params.placementId } if (bidderRequest.paapi?.enabled) { placement.ext.ae = bid?.ortb2Imp?.ext?.ae @@ -181,7 +181,7 @@ export const spec = { requestBody.site = _getSiteObj(bidderRequest) requestBody.device = _getDeviceObj() requestBody.id = bidderRequest.bidderRequestId; - requestBody.ext = {'ce': (storage.cookiesAreEnabled() ? 1 : 0)} + requestBody.ext = { 'ce': (storage.cookiesAreEnabled() ? 1 : 0) } // Attaching GDPR Consent Params if (bidderRequest && bidderRequest.gdprConsent) { diff --git a/modules/chromeAiRtdProvider.js b/modules/chromeAiRtdProvider.js index 9fd2d4c6639..75f17b6312a 100644 --- a/modules/chromeAiRtdProvider.js +++ b/modules/chromeAiRtdProvider.js @@ -15,6 +15,7 @@ export const CONSTANTS = Object.freeze({ STORAGE_KEY: 'chromeAi_detected_data', // Single key for both language and keywords MIN_TEXT_LENGTH: 20, ACTIVATION_EVENTS: ['click', 'keydown', 'mousedown', 'touchend', 'pointerdown', 'pointerup'], + MAX_TEXT_LENGTH: 1000, // Limit to prevent QuotaExceededError with Chrome AI APIs DEFAULT_CONFIG: { languageDetector: { enabled: true, @@ -94,6 +95,11 @@ export const getPageText = () => { logMessage(`${CONSTANTS.LOG_PRE_FIX} Not enough text content (length: ${text?.length || 0}) for processing.`); return null; } + // Limit text length to prevent QuotaExceededError with Chrome AI APIs + if (text.length > CONSTANTS.MAX_TEXT_LENGTH) { + logMessage(`${CONSTANTS.LOG_PRE_FIX} Truncating text from ${text.length} to ${CONSTANTS.MAX_TEXT_LENGTH} chars.`); + return text.substring(0, CONSTANTS.MAX_TEXT_LENGTH); + } return text; }; diff --git a/modules/chtnwBidAdapter.js b/modules/chtnwBidAdapter.js index 3aea0016679..31c2c7bf342 100644 --- a/modules/chtnwBidAdapter.js +++ b/modules/chtnwBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { generateUUID, _each, @@ -9,11 +9,11 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getStorageManager } from '../src/storageManager.js'; import { ajax } from '../src/ajax.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://prebid.cht.hinet.net/api/v1'; const BIDDER_CODE = 'chtnw'; const COOKIE_NAME = '__htid'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const { getConfig } = config; diff --git a/modules/clickforceBidAdapter.js b/modules/clickforceBidAdapter.js index 6308774faad..d45a701cd5e 100644 --- a/modules/clickforceBidAdapter.js +++ b/modules/clickforceBidAdapter.js @@ -1,6 +1,6 @@ import { _each } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; /** diff --git a/modules/clickioBidAdapter.js b/modules/clickioBidAdapter.js index 3ba5094ffe5..2028256f18b 100644 --- a/modules/clickioBidAdapter.js +++ b/modules/clickioBidAdapter.js @@ -1,7 +1,7 @@ -import {deepSetValue} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { deepSetValue } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'clickio'; const IAB_GVL_ID = 1500; @@ -23,7 +23,7 @@ export const spec = { gvlid: IAB_GVL_ID, supportedMediaTypes: [BANNER], buildRequests(bidRequests, bidderRequest) { - const data = converter.toORTB({bidRequests, bidderRequest}) + const data = converter.toORTB({ bidRequests, bidderRequest }) return [{ method: 'POST', url: 'https://o.clickiocdn.com/bids', @@ -34,7 +34,7 @@ export const spec = { return true; }, interpretResponse(response, request) { - const bids = converter.fromORTB({response: response.body, request: request.data}).bids; + const bids = converter.fromORTB({ response: response.body, request: request.data }).bids; return bids; }, getUserSyncs(syncOptions, _, gdprConsent, uspConsent, gppConsent = {}) { diff --git a/modules/clydoBidAdapter.js b/modules/clydoBidAdapter.js index 1ffdd3df474..2f00d439748 100644 --- a/modules/clydoBidAdapter.js +++ b/modules/clydoBidAdapter.js @@ -35,7 +35,7 @@ export const spec = { return allowedRegions.includes(region); }, buildRequests: function(validBidRequests, bidderRequest) { - const data = converter.toORTB({bidRequests: validBidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests: validBidRequests, bidderRequest }); const { partnerId, region } = validBidRequests[0].params; if (Array.isArray(data.imp)) { @@ -47,7 +47,7 @@ export const spec = { const mediaType = imp.banner ? 'banner' : (imp.video ? 'video' : (imp.native ? 'native' : '*')); let floor = deepAccess(srcBid, 'floor'); if (!floor && isFn(srcBid.getFloor)) { - const floorInfo = srcBid.getFloor({currency: DEFAULT_CURRENCY, mediaType, size: '*'}); + const floorInfo = srcBid.getFloor({ currency: DEFAULT_CURRENCY, mediaType, size: '*' }); if (floorInfo && typeof floorInfo.floor === 'number') { floor = floorInfo.floor; } @@ -84,7 +84,7 @@ export const spec = { try { const parsed = JSON.parse(b.adm); if (parsed && parsed.native && Array.isArray(parsed.native.assets)) { - return {...b, adm: JSON.stringify(parsed.native)}; + return { ...b, adm: JSON.stringify(parsed.native) }; } } catch (e) {} } @@ -93,7 +93,7 @@ export const spec = { })) } : body; - bids = converter.fromORTB({response: normalized, request: request.data}).bids; + bids = converter.fromORTB({ response: normalized, request: request.data }).bids; } return bids; }, diff --git a/modules/codefuelBidAdapter.js b/modules/codefuelBidAdapter.js index 235ef613992..c8ec470dce5 100644 --- a/modules/codefuelBidAdapter.js +++ b/modules/codefuelBidAdapter.js @@ -1,6 +1,6 @@ -import {isArray, setOnAny} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { isArray, setOnAny } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -16,7 +16,7 @@ const CURRENCY = 'USD'; export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [ BANNER ], + supportedMediaTypes: [BANNER], aliases: ['ex'], // short code /** * Determines whether or not the given bid request is valid. diff --git a/modules/coinzillaBidAdapter.js b/modules/coinzillaBidAdapter.js index 9ae2c74547d..fe09221790d 100644 --- a/modules/coinzillaBidAdapter.js +++ b/modules/coinzillaBidAdapter.js @@ -1,5 +1,5 @@ import { parseSizesInput } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/colombiaBidAdapter.js b/modules/colombiaBidAdapter.js index 9beb4117986..e791c19fb9b 100644 --- a/modules/colombiaBidAdapter.js +++ b/modules/colombiaBidAdapter.js @@ -1,7 +1,7 @@ import { ajax } from '../src/ajax.js'; import * as utils from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'colombia'; const ENDPOINT_URL = 'https://ade.clmbtech.com/cde/prebid.htm'; diff --git a/modules/colossussspBidAdapter.js b/modules/colossussspBidAdapter.js index 951a4144522..d0728989c3e 100644 --- a/modules/colossussspBidAdapter.js +++ b/modules/colossussspBidAdapter.js @@ -27,7 +27,7 @@ function getUserId(eids, id, source, uidExt) { } eids.push({ source, - uids: [ uid ] + uids: [uid] }); } } diff --git a/modules/conceptxBidAdapter.js b/modules/conceptxBidAdapter.js index 67ebd88e4e4..eef57e0aaa8 100644 --- a/modules/conceptxBidAdapter.js +++ b/modules/conceptxBidAdapter.js @@ -1,81 +1,258 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -// import { logError, logInfo, logWarn, parseUrl } from '../src/utils.js'; const BIDDER_CODE = 'conceptx'; -const ENDPOINT_URL = 'https://conceptx.cncpt-central.com/openrtb'; -// const LOG_PREFIX = 'ConceptX: '; +const ENDPOINT_URL = 'https://cxba-s2s.cncpt.dk/openrtb2/auction'; const GVLID = 1340; export const spec = { code: BIDDER_CODE, supportedMediaTypes: [BANNER], gvlid: GVLID, + isBidRequestValid: function (bid) { - return !!(bid.bidId && bid.params.site && bid.params.adunit); + return !!(bid.bidId && bid.params && bid.params.adunit); }, buildRequests: function (validBidRequests, bidderRequest) { - // logWarn(LOG_PREFIX + 'all native assets containing URL should be sent as placeholders with sendId(icon, image, clickUrl, displayUrl, privacyLink, privacyIcon)'); const requests = []; - let requestUrl = `${ENDPOINT_URL}` - if (bidderRequest && bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - requestUrl += '?gdpr_applies=' + bidderRequest.gdprConsent.gdprApplies; - requestUrl += '&consentString=' + bidderRequest.gdprConsent.consentString; - } - for (var i = 0; i < validBidRequests.length; i++) { - const requestParent = { adUnits: [], meta: {} }; - const bid = validBidRequests[i] - const { adUnitCode, auctionId, bidId, bidder, bidderRequestId, ortb2 } = bid - requestParent.meta = { adUnitCode, auctionId, bidId, bidder, bidderRequestId, ortb2 } - - const { site, adunit } = bid.params - const adUnit = { site, adunit, targetId: bid.bidId } - if (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) adUnit.dimensions = bid.mediaTypes.banner.sizes - requestParent.adUnits.push(adUnit); + + for (let i = 0; i < validBidRequests.length; i++) { + const bid = validBidRequests[i]; + const { + adUnitCode, + auctionId, + bidId, + bidder, + bidderRequestId, + ortb2 = {}, + } = bid; + const params = bid.params || {}; + + // PBS URL + GDPR query params + let url = ENDPOINT_URL; + const query = []; + + // Only add GDPR params when gdprApplies is explicitly 0 or 1 + if (bidderRequest && bidderRequest.gdprConsent) { + let gdprApplies = bidderRequest.gdprConsent.gdprApplies; + if (typeof gdprApplies === 'boolean') { + gdprApplies = gdprApplies ? 1 : 0; + } + if (gdprApplies === 0 || gdprApplies === 1) { + query.push('gdpr_applies=' + gdprApplies); + if (bidderRequest.gdprConsent.consentString) { + query.push( + 'gdpr_consent=' + + encodeURIComponent(bidderRequest.gdprConsent.consentString) + ); + } + } + } + + if (query.length) { + url += '?' + query.join('&'); + } + + // site + const page = + params.site || (ortb2.site && ortb2.site.page) || ''; + const domain = + params.domain || (ortb2.site && ortb2.site.domain) || page; + + const site = { + id: domain || page || adUnitCode, + domain: domain || '', + page: page || '', + }; + + // banner sizes from mediaTypes.banner.sizes + const formats = []; + if ( + bid.mediaTypes && + bid.mediaTypes.banner && + bid.mediaTypes.banner.sizes + ) { + let sizes = bid.mediaTypes.banner.sizes; + if (sizes.length && typeof sizes[0] === 'number') { + sizes = [sizes]; + } + for (let j = 0; j < sizes.length; j++) { + const size = sizes[j]; + if (size && size.length === 2) { + formats.push({ w: size[0], h: size[1] }); + } + } + } + + const banner = formats.length ? { format: formats } : {}; + + // currency & timeout + let currency = 'DKK'; + if ( + bidderRequest && + bidderRequest.currency && + bidderRequest.currency.adServerCurrency + ) { + currency = bidderRequest.currency.adServerCurrency; + } + + const tmax = (bidderRequest && bidderRequest.timeout) || 500; + + // device + const ua = + typeof navigator !== 'undefined' && navigator.userAgent + ? navigator.userAgent + : 'Mozilla/5.0'; + const device = { ua }; + + // build OpenRTB request for PBS with stored requests + const ortbRequest = { + id: auctionId || bidId, + site, + device, + cur: [currency], + tmax, + imp: [ + { + id: bidId, + banner, + ext: { + prebid: { + storedrequest: { + id: params.adunit, + }, + }, + }, + }, + ], + ext: { + prebid: { + storedrequest: { + id: 'cx_global', + }, + custommeta: { + adUnitCode, + auctionId, + bidId, + bidder, + bidderRequestId, + }, + }, + }, + }; + + // GDPR in body + if (bidderRequest && bidderRequest.gdprConsent) { + let gdprAppliesBody = bidderRequest.gdprConsent.gdprApplies; + if (typeof gdprAppliesBody === 'boolean') { + gdprAppliesBody = gdprAppliesBody ? 1 : 0; + } + + if (!ortbRequest.user) ortbRequest.user = {}; + if (!ortbRequest.user.ext) ortbRequest.user.ext = {}; + + if (bidderRequest.gdprConsent.consentString) { + ortbRequest.user.ext.consent = + bidderRequest.gdprConsent.consentString; + } + + if (!ortbRequest.regs) ortbRequest.regs = {}; + if (!ortbRequest.regs.ext) ortbRequest.regs.ext = {}; + + if (gdprAppliesBody === 0 || gdprAppliesBody === 1) { + ortbRequest.regs.ext.gdpr = gdprAppliesBody; + } + } + + // user IDs -> user.ext.eids + if (bid.userIdAsEids && bid.userIdAsEids.length) { + if (!ortbRequest.user) ortbRequest.user = {}; + if (!ortbRequest.user.ext) ortbRequest.user.ext = {}; + ortbRequest.user.ext.eids = bid.userIdAsEids; + } + requests.push({ method: 'POST', - url: requestUrl, + url, options: { - withCredentials: false, + withCredentials: true, }, - data: JSON.stringify(requestParent), + data: JSON.stringify(ortbRequest), }); } return requests; }, - interpretResponse: function (serverResponse, bidRequest) { - const bidResponses = []; - const bidResponsesFromServer = serverResponse.body.bidResponses; - if (Array.isArray(bidResponsesFromServer) && bidResponsesFromServer.length === 0) { - return bidResponses - } - const firstBid = bidResponsesFromServer[0] - if (!firstBid) { - return bidResponses + interpretResponse: function (serverResponse, request) { + const body = + serverResponse && serverResponse.body ? serverResponse.body : {}; + + // PBS OpenRTB: seatbid[].bid[] + if ( + !body.seatbid || + !Array.isArray(body.seatbid) || + body.seatbid.length === 0 + ) { + return []; } - const firstSeat = firstBid.ads[0] - if (!firstSeat) { - return bidResponses + + const currency = body.cur || 'DKK'; + const bids = []; + + // recover referrer (site.page) from original request + let referrer = ''; + try { + if (request && request.data) { + const originalReq = + typeof request.data === 'string' + ? JSON.parse(request.data) + : request.data; + if (originalReq && originalReq.site && originalReq.site.page) { + referrer = originalReq.site.page; + } + } + } catch (_) {} + + for (let i = 0; i < body.seatbid.length; i++) { + const seatbid = body.seatbid[i]; + if (!seatbid.bid || !Array.isArray(seatbid.bid)) continue; + + for (let j = 0; j < seatbid.bid.length; j++) { + const b = seatbid.bid[j]; + + if (!b || typeof b.price !== 'number' || !b.adm) continue; + + bids.push({ + requestId: b.impid || b.id, + cpm: b.price, + width: b.w, + height: b.h, + creativeId: b.crid || b.id || '', + dealId: b.dealid || b.dealId || undefined, + currency, + netRevenue: true, + ttl: 300, + referrer, + ad: b.adm, + }); + } } - const bidResponse = { - requestId: firstSeat.requestId, - cpm: firstSeat.cpm, - width: firstSeat.width, - height: firstSeat.height, - creativeId: firstSeat.creativeId, - dealId: firstSeat.dealId, - currency: firstSeat.currency, - netRevenue: true, - ttl: firstSeat.ttl, - referrer: firstSeat.referrer, - ad: firstSeat.html - }; - bidResponses.push(bidResponse); - return bidResponses; + + return bids; + }, + + /** + * Cookie sync for conceptx is handled by the enrichment script's runPbsCookieSync, + * which calls https://cxba-s2s.cncpt.dk/cookie_sync with bidders. The PBS returns + * bidder_status with usersync URLs, and the script runs iframe/image syncs. + * The adapter does not return sync URLs here since those come from the cookie_sync + * endpoint, not the auction response. + */ + getUserSyncs: function () { + return []; }, +}; -} registerBidder(spec); diff --git a/modules/concertAnalyticsAdapter.js b/modules/concertAnalyticsAdapter.js index 75c0c33966c..99b6f8b8f20 100644 --- a/modules/concertAnalyticsAdapter.js +++ b/modules/concertAnalyticsAdapter.js @@ -1,5 +1,5 @@ import { logMessage } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; @@ -20,7 +20,7 @@ const { let queue = []; -const concertAnalytics = Object.assign(adapter({url, analyticsType}), { +const concertAnalytics = Object.assign(adapter({ url, analyticsType }), { track({ eventType, args }) { switch (eventType) { case BID_RESPONSE: diff --git a/modules/connatixBidAdapter.js b/modules/connatixBidAdapter.js index 7b22de3aa1d..3bc5f300e2a 100644 --- a/modules/connatixBidAdapter.js +++ b/modules/connatixBidAdapter.js @@ -406,7 +406,7 @@ export const spec = { } const requestTimeout = connatixBidRequestTimeout.timeout; const timeout = isNumber(requestTimeout) ? requestTimeout : config.getConfig('bidderTimeout'); - spec.triggerEvent({type: 'Timeout', timeout, context}); + spec.triggerEvent({ type: 'Timeout', timeout, context }); }, /** @@ -416,9 +416,9 @@ export const spec = { if (bidWinData == null) { return; } - const {bidder, cpm, requestId, bidId, adUnitCode, timeToRespond, auctionId} = bidWinData; + const { bidder, cpm, requestId, bidId, adUnitCode, timeToRespond, auctionId } = bidWinData; - spec.triggerEvent({type: 'BidWon', bestBidBidder: bidder, bestBidPrice: cpm, requestId, bidId, adUnitCode, timeToRespond, auctionId, context}); + spec.triggerEvent({ type: 'BidWon', bestBidBidder: bidder, bestBidPrice: cpm, requestId, bidId, adUnitCode, timeToRespond, auctionId, context }); }, triggerEvent(data) { diff --git a/modules/connectIdSystem.js b/modules/connectIdSystem.js index 006cb06d005..b0f8e4836ef 100644 --- a/modules/connectIdSystem.js +++ b/modules/connectIdSystem.js @@ -5,13 +5,13 @@ * @requires module:modules/userId */ -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {getStorageManager, STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE} from '../src/storageManager.js'; -import {formatQS, isNumber, isPlainObject, logError, parseUrl} from '../src/utils.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { getStorageManager, STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE } from '../src/storageManager.js'; +import { formatQS, isNumber, isPlainObject, logError, parseUrl } from '../src/utils.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -42,7 +42,7 @@ const O_AND_O_DOMAINS = [ 'techcrunch.com', 'autoblog.com', ]; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** * Stores the ConnectID object in browser storage according to storage configuration @@ -201,7 +201,7 @@ export const connectIdSubmodule = { return undefined; } return (isPlainObject(value) && (value.connectId || value.connectid)) - ? {connectId: value.connectId || value.connectid} : undefined; + ? { connectId: value.connectId || value.connectid } : undefined; }, /** * Gets the Yahoo ConnectID @@ -239,7 +239,7 @@ export const connectIdSubmodule = { if (!shouldResync) { storedId.lastUsed = Date.now(); storeObject(storedId, storageConfig); - return {id: storedId}; + return { id: storedId }; } } @@ -316,9 +316,9 @@ export const connectIdSubmodule = { }; const endpoint = UPS_ENDPOINT.replace(PLACEHOLDER, params.pixelId); const url = `${params.endpoint || endpoint}?${formatQS(data)}`; - connectIdSubmodule.getAjaxFn()(url, callbacks, null, {method: 'GET', withCredentials: true}); + connectIdSubmodule.getAjaxFn()(url, callbacks, null, { method: 'GET', withCredentials: true }); }; - const result = {callback: resp}; + const result = { callback: resp }; if (shouldResync && storedId) { result.id = storedId; } diff --git a/modules/connectadBidAdapter.js b/modules/connectadBidAdapter.js index 464499b5f7d..71f8986e604 100644 --- a/modules/connectadBidAdapter.js +++ b/modules/connectadBidAdapter.js @@ -1,9 +1,9 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, deepSetValue, mergeDeep, logWarn, generateUUID } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js' -import {config} from '../src/config.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { config } from '../src/config.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const BIDDER_CODE = 'connectad'; const BIDDER_CODE_ALIAS = 'connectadrealtime'; @@ -13,7 +13,7 @@ const SUPPORTED_MEDIA_TYPES = [BANNER]; export const spec = { code: BIDDER_CODE, gvlid: 138, - aliases: [ BIDDER_CODE_ALIAS ], + aliases: [BIDDER_CODE_ALIAS], supportedMediaTypes: SUPPORTED_MEDIA_TYPES, isBidRequestValid: function(bid) { diff --git a/modules/consentManagementGpp.ts b/modules/consentManagementGpp.ts index fcbcaeb664c..0f7c5b38550 100644 --- a/modules/consentManagementGpp.ts +++ b/modules/consentManagementGpp.ts @@ -4,15 +4,15 @@ * and make it available for any GPP supported adapters to read/pass this information to * their system and for various other features/modules in Prebid.js. */ -import {deepSetValue, isEmpty, isPlainObject, isStr, logInfo, logWarn} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {gppDataHandler} from '../src/adapterManager.js'; -import {enrichFPD} from '../src/fpd/enrichment.js'; -import {cmpClient, MODE_CALLBACK} from '../libraries/cmp/cmpClient.js'; -import {PbPromise, defer} from '../src/utils/promise.js'; -import {type CMConfig, configParser} from '../libraries/consentManagement/cmUtils.js'; -import {createCmpEventManager, type CmpEventManager} from '../libraries/cmp/cmpEventUtils.js'; -import {CONSENT_GPP} from "../src/consentHandler.ts"; +import { deepSetValue, isEmpty, isPlainObject, isStr, logInfo, logWarn } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { gppDataHandler } from '../src/adapterManager.js'; +import { enrichFPD } from '../src/fpd/enrichment.js'; +import { cmpClient, MODE_CALLBACK } from '../libraries/cmp/cmpClient.js'; +import { PbPromise, defer } from '../src/utils/promise.js'; +import { type CMConfig, configParser } from '../libraries/consentManagement/cmUtils.js'; +import { createCmpEventManager, type CmpEventManager } from '../libraries/cmp/cmpEventUtils.js'; +import { CONSENT_GPP } from "../src/consentHandler.ts"; export let consentConfig = {} as any; @@ -142,7 +142,7 @@ export class GPPClient { } refresh() { - return this.cmp({command: 'ping'}).then(this.init.bind(this)); + return this.cmp({ command: 'ping' }).then(this.init.bind(this)); } /** diff --git a/modules/consentManagementTcf.ts b/modules/consentManagementTcf.ts index 673a2d6f269..48fe05e1723 100644 --- a/modules/consentManagementTcf.ts +++ b/modules/consentManagementTcf.ts @@ -4,16 +4,16 @@ * and make it available for any GDPR supported adapters to read/pass this information to * their system. */ -import {deepSetValue, isStr, logInfo} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {gdprDataHandler} from '../src/adapterManager.js'; -import {registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js'; -import {enrichFPD} from '../src/fpd/enrichment.js'; -import {cmpClient} from '../libraries/cmp/cmpClient.js'; -import {configParser} from '../libraries/consentManagement/cmUtils.js'; -import {createCmpEventManager, type CmpEventManager} from '../libraries/cmp/cmpEventUtils.js'; -import {CONSENT_GDPR} from "../src/consentHandler.ts"; -import type {CMConfig} from "../libraries/consentManagement/cmUtils.ts"; +import { deepSetValue, isStr, logInfo } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { gdprDataHandler } from '../src/adapterManager.js'; +import { registerOrtbProcessor, REQUEST } from '../src/pbjsORTB.js'; +import { enrichFPD } from '../src/fpd/enrichment.js'; +import { cmpClient } from '../libraries/cmp/cmpClient.js'; +import { configParser } from '../libraries/consentManagement/cmUtils.js'; +import { createCmpEventManager, type CmpEventManager } from '../libraries/cmp/cmpEventUtils.js'; +import { CONSENT_GDPR } from "../src/consentHandler.ts"; +import type { CMConfig } from "../libraries/consentManagement/cmUtils.ts"; export let consentConfig: any = {}; export let gdprScope; @@ -145,7 +145,7 @@ function parseConsentData(consentObject): TCFConsentData { } if (checkData()) { - throw Object.assign(new Error(`CMP returned unexpected value during lookup process.`), {args: [consentObject]}) + throw Object.assign(new Error(`CMP returned unexpected value during lookup process.`), { args: [consentObject] }) } else { return toConsentData(consentObject); } @@ -203,7 +203,7 @@ export function setConsentConfig(config) { } gdprScope = tcfConfig?.defaultGdprScope === true; dsaPlatform = !!tcfConfig?.dsaPlatform; - consentConfig = parseConfig({gdpr: tcfConfig}); + consentConfig = parseConfig({ gdpr: tcfConfig }); return consentConfig.loadConsentData?.()?.catch?.(() => null); } config.getConfig('consentManagement', config => setConsentConfig(config.consentManagement)); @@ -234,4 +234,4 @@ export function setOrtbAdditionalConsent(ortbRequest, bidderRequest) { } } -registerOrtbProcessor({type: REQUEST, name: 'gdprAddtlConsent', fn: setOrtbAdditionalConsent}) +registerOrtbProcessor({ type: REQUEST, name: 'gdprAddtlConsent', fn: setOrtbAdditionalConsent }) diff --git a/modules/consentManagementUsp.ts b/modules/consentManagementUsp.ts index 2485885e476..dee29fff6fb 100644 --- a/modules/consentManagementUsp.ts +++ b/modules/consentManagementUsp.ts @@ -4,15 +4,15 @@ * information and make it available for any USP (CCPA) supported adapters to * read/pass this information to their system. */ -import {deepSetValue, isNumber, isPlainObject, isStr, logError, logInfo, logWarn} from '../src/utils.js'; -import {config} from '../src/config.js'; -import adapterManager, {uspDataHandler} from '../src/adapterManager.js'; -import {timedAuctionHook} from '../src/utils/perfMetrics.js'; -import {getHook} from '../src/hook.js'; -import {enrichFPD} from '../src/fpd/enrichment.js'; -import {cmpClient} from '../libraries/cmp/cmpClient.js'; -import type {IABCMConfig, StaticCMConfig} from "../libraries/consentManagement/cmUtils.ts"; -import type {CONSENT_USP} from "../src/consentHandler.ts"; +import { deepSetValue, isNumber, isPlainObject, isStr, logError, logInfo, logWarn } from '../src/utils.js'; +import { config } from '../src/config.js'; +import adapterManager, { uspDataHandler } from '../src/adapterManager.js'; +import { timedAuctionHook } from '../src/utils/perfMetrics.js'; +import { getHook } from '../src/hook.js'; +import { enrichFPD } from '../src/fpd/enrichment.js'; +import { cmpClient } from '../libraries/cmp/cmpClient.js'; +import type { IABCMConfig, StaticCMConfig } from "../libraries/consentManagement/cmUtils.ts"; +import type { CONSENT_USP } from "../src/consentHandler.ts"; const DEFAULT_CONSENT_API = 'iab'; const DEFAULT_CONSENT_TIMEOUT = 50; @@ -59,8 +59,8 @@ const uspCallMap = { /** * This function reads the consent string from the config to obtain the consent information of the user. */ -function lookupStaticConsentData({onSuccess, onError}) { - processUspData(staticConsentData, {onSuccess, onError}); +function lookupStaticConsentData({ onSuccess, onError }) { + processUspData(staticConsentData, { onSuccess, onError }); } /** @@ -68,13 +68,13 @@ function lookupStaticConsentData({onSuccess, onError}) { * Given the async nature of the USP's API, we pass in acting success/error callback functions to exit this function * based on the appropriate result. */ -function lookupUspConsent({onSuccess, onError}) { +function lookupUspConsent({ onSuccess, onError }) { function handleUspApiResponseCallbacks() { const uspResponse = {} as any; function afterEach() { if (uspResponse.usPrivacy) { - processUspData(uspResponse, {onSuccess, onError}) + processUspData(uspResponse, { onSuccess, onError }) } else { onError('Unable to get USP consent string.'); } @@ -197,7 +197,7 @@ export const requestBidsHook = timedAuctionHook('usp', function requestBidsHook( * @param {function(string): void} callbacks.onSuccess - Callback accepting the resolved USP consent string. * @param {function(string, ...Object?): void} callbacks.onError - Callback accepting an error message and any extra error arguments (used purely for logging). */ -function processUspData(consentObject, {onSuccess, onError}) { +function processUspData(consentObject, { onSuccess, onError }) { const valid = !!(consentObject && consentObject.usPrivacy); if (!valid) { onError(`USPAPI returned unexpected value during lookup process.`, consentObject); diff --git a/modules/consumableBidAdapter.js b/modules/consumableBidAdapter.js index 8a565788764..b8a19ab3141 100644 --- a/modules/consumableBidAdapter.js +++ b/modules/consumableBidAdapter.js @@ -1,5 +1,5 @@ import { logWarn, deepAccess, isArray, deepSetValue, isFn, isPlainObject } from '../src/utils.js'; -import {config} from '../src/config.js'; +import { config } from '../src/config.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; diff --git a/modules/conversantBidAdapter.ts b/modules/conversantBidAdapter.ts index 8563611b337..7d6d56788af 100644 --- a/modules/conversantBidAdapter.ts +++ b/modules/conversantBidAdapter.ts @@ -10,10 +10,10 @@ import { mergeDeep, parseUrl, } from '../src/utils.js'; -import {type BidderSpec, registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {ORTB_MTYPES} from '../libraries/ortbConverter/processors/mediaType.js'; +import { type BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { ORTB_MTYPES } from '../libraries/ortbConverter/processors/mediaType.js'; // Maintainer: mediapsr@epsilon.com @@ -126,7 +126,7 @@ const converter = ortbConverter({ if (bidRequest.mediaTypes && !bidRequest.mediaTypes.banner) return; if (bidRequest.params.position) { // fillBannerImp looks for mediaTypes.banner.pos so put it under the right name here - mergeDeep(bidRequest, {mediaTypes: {banner: {pos: bidRequest.params.position}}}); + mergeDeep(bidRequest, { mediaTypes: { banner: { pos: bidRequest.params.position } } }); } fillBannerImp(imp, bidRequest, context); }, @@ -183,7 +183,7 @@ export const spec: BidderSpec = { }, buildRequests: function(bidRequests, bidderRequest) { - const payload = converter.toORTB({bidderRequest, bidRequests}); + const payload = converter.toORTB({ bidderRequest, bidRequests }); return { method: 'POST', url: makeBidUrl(bidRequests[0]), @@ -198,7 +198,7 @@ export const spec: BidderSpec = { * @return {Bid[]} An array of bids which were nested inside the server. */ interpretResponse: function(serverResponse, bidRequest) { - return converter.fromORTB({request: bidRequest.data, response: serverResponse.body}); + return converter.fromORTB({ request: bidRequest.data, response: serverResponse.body }); }, /** @@ -228,7 +228,7 @@ export const spec: BidderSpec = { responses.forEach(response => { if (response?.body?.ext) { const ext = response.body.ext; - const pixels = [{urls: ext.fsyncs, type: 'iframe'}, {urls: ext.psyncs, type: 'image'}] + const pixels = [{ urls: ext.fsyncs, type: 'iframe' }, { urls: ext.psyncs, type: 'image' }] .filter((entry) => { return entry.urls && Array.isArray(entry.urls) && entry.urls.length > 0 && @@ -242,7 +242,7 @@ export const spec: BidderSpec = { if (Object.keys(urlInfo.search).length === 0) { delete urlInfo.search; } - return {type: entry.type, url: buildUrl(urlInfo)}; + return { type: entry.type, url: buildUrl(urlInfo) }; }) .reduce((x, y) => x.concat(y), []); }) diff --git a/modules/craftBidAdapter.js b/modules/craftBidAdapter.js index cbb3d047e0b..34d2bb35f17 100644 --- a/modules/craftBidAdapter.js +++ b/modules/craftBidAdapter.js @@ -1,17 +1,17 @@ -import {getBidRequest} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; -import {interpretResponseUtil} from '../libraries/interpretResponseUtils/index.js'; +import { getBidRequest } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { ajax } from '../src/ajax.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; +import { interpretResponseUtil } from '../libraries/interpretResponseUtils/index.js'; const BIDDER_CODE = 'craft'; const URL_BASE = 'https://gacraft.jp/prebid-v3'; const TTL = 360; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -54,7 +54,8 @@ export const spec = { // TODO: this collects everything it finds, except for the canonical URL rd_ref: bidderRequest.refererInfo.topmostLocation, rd_top: bidderRequest.refererInfo.reachedTop, - rd_ifs: bidderRequest.refererInfo.numIframes}; + rd_ifs: bidderRequest.refererInfo.numIframes + }; if (bidderRequest.refererInfo.stack) { refererinfo.rd_stk = bidderRequest.refererInfo.stack.join(','); } @@ -68,9 +69,9 @@ export const spec = { return request; }, - interpretResponse: function(serverResponse, {bidderRequest}) { + interpretResponse: function(serverResponse, { bidderRequest }) { try { - const bids = interpretResponseUtil(serverResponse, {bidderRequest}, serverBid => { + const bids = interpretResponseUtil(serverResponse, { bidderRequest }, serverBid => { const rtbBid = getRtbBid(serverBid); if (rtbBid && rtbBid.cpm !== 0 && this.supportedMediaTypes.includes(rtbBid.ad_type)) { const bid = newBid(serverBid, rtbBid, bidderRequest); diff --git a/modules/criteoBidAdapter.js b/modules/criteoBidAdapter.js index 9965cd1cb2b..a6ef6ba26e6 100644 --- a/modules/criteoBidAdapter.js +++ b/modules/criteoBidAdapter.js @@ -1,15 +1,15 @@ -import {deepSetValue, isArray, logError, logWarn, parseUrl, triggerPixel, deepAccess, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {Renderer} from '../src/Renderer.js'; -import {OUTSTREAM} from '../src/video.js'; -import {ajax} from '../src/ajax.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {ortb25Translator} from '../libraries/ortb2.5Translator/translator.js'; -import {config} from '../src/config.js'; +import { deepSetValue, isArray, logError, logWarn, parseUrl, triggerPixel, deepAccess, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { Renderer } from '../src/Renderer.js'; +import { OUTSTREAM } from '../src/video.js'; +import { ajax } from '../src/ajax.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { ortb25Translator } from '../libraries/ortb2.5Translator/translator.js'; +import { config } from '../src/config.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -165,7 +165,7 @@ function bidResponse(buildBidResponse, bid, context) { } const bidResponse = buildBidResponse(bid, context); - const {bidRequest} = context; + const { bidRequest } = context; bidResponse.currency = bid?.ext?.cur; @@ -374,7 +374,7 @@ export const spec = { const context = buildContext(bidRequests, bidderRequest); const url = buildCdbUrl(context); - const data = CONVERTER.toORTB({bidderRequest, bidRequests, context}); + const data = CONVERTER.toORTB({ bidderRequest, bidRequests, context }); if (data) { return { @@ -399,7 +399,7 @@ export const spec = { return []; // no bid } - const interpretedResponse = CONVERTER.fromORTB({response: response.body, request: request.data}); + const interpretedResponse = CONVERTER.fromORTB({ response: response.body, request: request.data }); const bids = interpretedResponse.bids || []; const fledgeAuctionConfigs = response.body?.ext?.igi?.filter(igi => isArray(igi?.igs)) diff --git a/modules/currency.ts b/modules/currency.ts index 34b29d94047..a45c79ef9ec 100644 --- a/modules/currency.ts +++ b/modules/currency.ts @@ -1,17 +1,17 @@ -import {deepSetValue, logError, logInfo, logMessage, logWarn} from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { deepSetValue, logError, logInfo, logMessage, logWarn } from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; import { EVENTS, REJECTION_REASON } from '../src/constants.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {getHook} from '../src/hook.js'; -import {defer} from '../src/utils/promise.js'; -import {registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js'; -import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js'; -import {on as onEvent, off as offEvent} from '../src/events.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { getHook } from '../src/hook.js'; +import { defer } from '../src/utils/promise.js'; +import { registerOrtbProcessor, REQUEST } from '../src/pbjsORTB.js'; +import { timedAuctionHook, timedBidResponseHook } from '../src/utils/perfMetrics.js'; +import { on as onEvent, off as offEvent } from '../src/events.js'; import { enrichFPD } from '../src/fpd/enrichment.js'; import { timeoutQueue } from '../libraries/timeoutQueue/timeoutQueue.js'; -import type {Currency, BidderCode} from "../src/types/common.d.ts"; -import {addApiMethod} from "../src/prebid.ts"; +import type { Currency, BidderCode } from "../src/types/common.d.ts"; +import { addApiMethod } from "../src/prebid.ts"; const DEFAULT_CURRENCY_RATE_URL = 'https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=$$TODAY$$'; const CURRENCY_RATE_PRECISION = 4; @@ -218,10 +218,10 @@ function initCurrency() { export function resetCurrency() { if (currencySupportEnabled) { - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); - getHook('responsesReady').getHooks({hook: responsesReadyHook}).remove(); - enrichFPD.getHooks({hook: enrichFPDHook}).remove(); - getHook('requestBids').getHooks({hook: requestBidsHook}).remove(); + getHook('addBidResponse').getHooks({ hook: addBidResponseHook }).remove(); + getHook('responsesReady').getHooks({ hook: responsesReadyHook }).remove(); + enrichFPD.getHooks({ hook: enrichFPDHook }).remove(); + getHook('requestBids').getHooks({ hook: requestBidsHook }).remove(); offEvent(EVENTS.AUCTION_TIMEOUT, rejectOnAuctionTimeout); offEvent(EVENTS.AUCTION_INIT, loadRates); delete getGlobal().convertCurrency; @@ -287,7 +287,7 @@ export const addBidResponseHook = timedBidResponseHook('currency', function addB } }); -function rejectOnAuctionTimeout({auctionId}) { +function rejectOnAuctionTimeout({ auctionId }) { bidResponseQueue = bidResponseQueue.filter(([fn, ctx, adUnitCode, bid, reject]) => { if (bid.auctionId === auctionId) { reject(REJECTION_REASON.CANNOT_CONVERT_CURRENCY) @@ -395,7 +395,7 @@ export function setOrtbCurrency(ortbRequest, bidderRequest, context) { } } -registerOrtbProcessor({type: REQUEST, name: 'currency', fn: setOrtbCurrency}); +registerOrtbProcessor({ type: REQUEST, name: 'currency', fn: setOrtbCurrency }); function enrichFPDHook(next, fpd) { return next(fpd.then(ortb2 => { diff --git a/modules/czechAdIdSystem.js b/modules/czechAdIdSystem.js index 62141dd7d62..854d16de73a 100644 --- a/modules/czechAdIdSystem.js +++ b/modules/czechAdIdSystem.js @@ -6,8 +6,8 @@ */ import { submodule } from '../src/hook.js' -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule diff --git a/modules/dacIdSystem.js b/modules/dacIdSystem.js index ffdadef18e8..c2ebe29c5ad 100644 --- a/modules/dacIdSystem.js +++ b/modules/dacIdSystem.js @@ -19,9 +19,9 @@ import { import { getStorageManager } from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; const MODULE_NAME = 'dacId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); export const FUUID_COOKIE_NAME = '_a1_f'; export const AONEID_COOKIE_NAME = '_a1_d'; diff --git a/modules/dailyhuntBidAdapter.js b/modules/dailyhuntBidAdapter.js index 7337c5417d3..6082cd3ee1d 100644 --- a/modules/dailyhuntBidAdapter.js +++ b/modules/dailyhuntBidAdapter.js @@ -1,10 +1,10 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as mediaTypes from '../src/mediaTypes.js'; -import {_map, deepAccess, isEmpty} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {parseNativeResponse, getBidFloor} from '../libraries/nexverseUtils/index.js'; +import { _map, deepAccess, isEmpty } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { parseNativeResponse, getBidFloor } from '../libraries/nexverseUtils/index.js'; const BIDDER_CODE = 'dailyhunt'; const BIDDER_ALIAS = 'dh'; @@ -47,7 +47,8 @@ const ORTB_NATIVE_PARAMS = { id: 4, name: 'data', type: 10 - }}; + } +}; // Extract key from collections. const extractKeyInfo = (collection, key) => { @@ -212,17 +213,17 @@ const createOrtbImpVideoObj = (bid, videoObj) => { return obj; } -export function getProtocols({protocols}) { +export function getProtocols({ protocols }) { const defaultValue = [2, 3, 5, 6, 7, 8]; const listProtocols = [ - {key: 'VAST_1_0', value: 1}, - {key: 'VAST_2_0', value: 2}, - {key: 'VAST_3_0', value: 3}, - {key: 'VAST_1_0_WRAPPER', value: 4}, - {key: 'VAST_2_0_WRAPPER', value: 5}, - {key: 'VAST_3_0_WRAPPER', value: 6}, - {key: 'VAST_4_0', value: 7}, - {key: 'VAST_4_0_WRAPPER', value: 8} + { key: 'VAST_1_0', value: 1 }, + { key: 'VAST_2_0', value: 2 }, + { key: 'VAST_3_0', value: 3 }, + { key: 'VAST_1_0_WRAPPER', value: 4 }, + { key: 'VAST_2_0_WRAPPER', value: 5 }, + { key: 'VAST_3_0_WRAPPER', value: 6 }, + { key: 'VAST_4_0', value: 7 }, + { key: 'VAST_4_0_WRAPPER', value: 8 } ]; if (protocols) { return listProtocols.filter(p => { diff --git a/modules/dataControllerModule/index.js b/modules/dataControllerModule/index.js index 7c88eae029a..9131ada680c 100644 --- a/modules/dataControllerModule/index.js +++ b/modules/dataControllerModule/index.js @@ -2,11 +2,11 @@ * This module validates the configuration and filters data accordingly * @module modules/dataController */ -import {config} from '../../src/config.js'; -import {getHook, module} from '../../src/hook.js'; -import {deepAccess, deepSetValue, prefixLog} from '../../src/utils.js'; -import {startAuction} from '../../src/prebid.js'; -import {timedAuctionHook} from '../../src/utils/perfMetrics.js'; +import { config } from '../../src/config.js'; +import { getHook, module } from '../../src/hook.js'; +import { deepAccess, deepSetValue, prefixLog } from '../../src/utils.js'; +import { startAuction } from '../../src/prebid.js'; +import { timedAuctionHook } from '../../src/utils/perfMetrics.js'; const LOG_PRE_FIX = 'Data_Controller : '; const ALL = '*'; @@ -163,13 +163,13 @@ export function init() { const dataController = dataControllerConfig && dataControllerConfig.dataController; if (!dataController) { _logger.logInfo(`Data Controller is not configured`); - startAuction.getHooks({hook: filterBidData}).remove(); + startAuction.getHooks({ hook: filterBidData }).remove(); return; } if (dataController.filterEIDwhenSDA && dataController.filterSDAwhenEID) { _logger.logInfo(`Data Controller can be configured with either filterEIDwhenSDA or filterSDAwhenEID`); - startAuction.getHooks({hook: filterBidData}).remove(); + startAuction.getHooks({ hook: filterBidData }).remove(); return; } confListener(); // unsubscribe config listener diff --git a/modules/datablocksBidAdapter.js b/modules/datablocksBidAdapter.js index 7f5a4bedd62..fdd4a14342b 100644 --- a/modules/datablocksBidAdapter.js +++ b/modules/datablocksBidAdapter.js @@ -1,16 +1,16 @@ -import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js'; -import {deepAccess, getWinDimensions, getWindowTop, isGptPubadsDefined} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; -import {isWebdriverEnabled} from '../libraries/webdriver/webdriver.js'; +import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js'; +import { deepAccess, getWinDimensions, getWindowTop, isGptPubadsDefined } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { ajax } from '../src/ajax.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; +import { isWebdriverEnabled, isSeleniumDetected } from '../libraries/webdriver/webdriver.js'; import { buildNativeRequest, parseNativeResponse } from '../libraries/nativeAssetsUtils.js'; -export const storage = getStorageManager({bidderCode: 'datablocks'}); +export const storage = getStorageManager({ bidderCode: 'datablocks' }); // DEFINE THE PREBID BIDDER SPEC export const spec = { @@ -18,7 +18,7 @@ export const spec = { code: 'datablocks', // DATABLOCKS SCOPED OBJECT - db_obj: {metrics_host: 'prebid.dblks.net', metrics: [], metrics_timer: null, metrics_queue_time: 1000, vis_optout: false, source_id: 0}, + db_obj: { metrics_host: 'prebid.dblks.net', metrics: [], metrics_timer: null, metrics_queue_time: 1000, vis_optout: false, source_id: 0 }, // STORE THE DATABLOCKS BUYERID IN STORAGE store_dbid: function(dbid) { @@ -112,7 +112,7 @@ export const spec = { // POST CONSOLIDATED METRICS BACK TO SERVER send_metrics: function() { // POST TO SERVER - ajax(`https://${this.db_obj.metrics_host}/a/pb/`, null, JSON.stringify(this.db_obj.metrics), {method: 'POST', withCredentials: true}); + ajax(`https://${this.db_obj.metrics_host}/a/pb/`, null, JSON.stringify(this.db_obj.metrics), { method: 'POST', withCredentials: true }); // RESET THE QUEUE OF METRIC DATA this.db_obj.metrics = []; @@ -155,10 +155,10 @@ export const spec = { if (typeof window['googletag'].pubads().addEventListener === 'function') { // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 window['googletag'].pubads().addEventListener('impressionViewable', function(event) { - scope.queue_metric({type: 'slot_view', source_id: scope.db_obj.source_id, auction_id: bid.auctionId, div_id: event.slot.getSlotElementId(), slot_id: event.slot.getSlotId().getAdUnitPath()}); + scope.queue_metric({ type: 'slot_view', source_id: scope.db_obj.source_id, auction_id: bid.auctionId, div_id: event.slot.getSlotElementId(), slot_id: event.slot.getSlotId().getAdUnitPath() }); }); window['googletag'].pubads().addEventListener('slotRenderEnded', function(event) { - scope.queue_metric({type: 'slot_render', source_id: scope.db_obj.source_id, auction_id: bid.auctionId, div_id: event.slot.getSlotElementId(), slot_id: event.slot.getSlotId().getAdUnitPath()}); + scope.queue_metric({ type: 'slot_render', source_id: scope.db_obj.source_id, auction_id: bid.auctionId, div_id: event.slot.getSlotElementId(), slot_id: event.slot.getSlotId().getAdUnitPath() }); }) } } @@ -386,7 +386,7 @@ export const spec = { // DATABLOCKS WON THE AUCTION - REPORT SUCCESS onBidWon: function(bid) { - this.queue_metric({type: 'bid_won', source_id: bid.params[0].source_id, req_id: bid.requestId, slot_id: bid.adUnitCode, auction_id: bid.auctionId, size: bid.size, cpm: bid.cpm, pb: bid.adserverTargeting.hb_pb, rt: bid.timeToRespond, ttl: bid.ttl}); + this.queue_metric({ type: 'bid_won', source_id: bid.params[0].source_id, req_id: bid.requestId, slot_id: bid.adUnitCode, auction_id: bid.auctionId, size: bid.size, cpm: bid.cpm, pb: bid.adserverTargeting.hb_pb, rt: bid.timeToRespond, ttl: bid.ttl }); }, // TARGETING HAS BEEN SET @@ -400,17 +400,17 @@ export const spec = { const bids = []; const resBids = deepAccess(rtbResponse, 'body.seatbid') || []; resBids.forEach(bid => { - const resultItem = {requestId: bid.id, cpm: bid.price, creativeId: bid.crid, currency: bid.currency || 'USD', netRevenue: true, ttl: bid.ttl || 360, meta: {advertiserDomains: bid.adomain}}; + const resultItem = { requestId: bid.id, cpm: bid.price, creativeId: bid.crid, currency: bid.currency || 'USD', netRevenue: true, ttl: bid.ttl || 360, meta: { advertiserDomains: bid.adomain } }; const mediaType = deepAccess(bid, 'ext.mtype') || ''; switch (mediaType) { case 'banner': - bids.push(Object.assign({}, resultItem, {mediaType: BANNER, width: bid.w, height: bid.h, ad: bid.adm})); + bids.push(Object.assign({}, resultItem, { mediaType: BANNER, width: bid.w, height: bid.h, ad: bid.adm })); break; case 'native': const nativeResult = JSON.parse(bid.adm); - bids.push(Object.assign({}, resultItem, {mediaType: NATIVE, native: parseNativeResponse(nativeResult.native)})); + bids.push(Object.assign({}, resultItem, { mediaType: NATIVE, native: parseNativeResponse(nativeResult.native) })); break; default: @@ -432,40 +432,11 @@ export class BotClientTests { }, selenium: function () { - let response = false; - - if (window && document) { - const results = [ - 'webdriver' in window, - '_Selenium_IDE_Recorder' in window, - 'callSelenium' in window, - '_selenium' in window, - '__webdriver_script_fn' in document, - '__driver_evaluate' in document, - '__webdriver_evaluate' in document, - '__selenium_evaluate' in document, - '__fxdriver_evaluate' in document, - '__driver_unwrapped' in document, - '__webdriver_unwrapped' in document, - '__selenium_unwrapped' in document, - '__fxdriver_unwrapped' in document, - '__webdriver_script_func' in document, - document.documentElement.getAttribute('selenium') !== null, - document.documentElement.getAttribute('webdriver') !== null, - document.documentElement.getAttribute('driver') !== null - ]; - - results.forEach(result => { - if (result === true) { - response = true; - } - }) - } - - return response; + return isSeleniumDetected(window, document); }, } } + doTests() { let response = false; for (const i of Object.keys(this.tests)) { diff --git a/modules/datawrkzBidAdapter.js b/modules/datawrkzBidAdapter.js index b75af264935..f09f824486a 100644 --- a/modules/datawrkzBidAdapter.js +++ b/modules/datawrkzBidAdapter.js @@ -176,7 +176,7 @@ function buildNativeRequest(bidRequest, bidderRequest) { assets.push(generateNativeDataObj(body, 'desc', ++counter)); } - const request = JSON.stringify({assets: assets}); + const request = JSON.stringify({ assets: assets }); const native = { request: request }; @@ -277,7 +277,7 @@ function getVideoAdUnitSize(bidRequest) { adH = parseInt(playerSize[0][1]); } } - return {adH: adH, adW: adW} + return { adH: adH, adW: adW } } /* Get mediatype of the adunit from request */ @@ -306,7 +306,7 @@ function generatePayload(imp, bidderRequest) { publisher: {} }; - const regs = {ext: {}}; + const regs = { ext: {} }; if (bidderRequest.uspConsent) { regs.ext.us_privacy = bidderRequest.uspConsent; diff --git a/modules/dchain.ts b/modules/dchain.ts index d2a3199f983..66ef00783e4 100644 --- a/modules/dchain.ts +++ b/modules/dchain.ts @@ -1,8 +1,8 @@ -import {config} from '../src/config.js'; -import {getHook} from '../src/hook.js'; -import {_each, deepAccess, deepClone, isArray, isPlainObject, isStr, logError, logWarn} from '../src/utils.js'; -import {timedBidResponseHook} from '../src/utils/perfMetrics.js'; -import type {DemandChain} from "../src/types/ortb/ext/dchain.d.ts"; +import { config } from '../src/config.js'; +import { getHook } from '../src/hook.js'; +import { _each, deepAccess, deepClone, isArray, isPlainObject, isStr, logError, logWarn } from '../src/utils.js'; +import { timedBidResponseHook } from '../src/utils/perfMetrics.js'; +import type { DemandChain } from "../src/types/ortb/ext/dchain.d.ts"; const shouldBeAString = ' should be a string'; const shouldBeAnObject = ' should be an object'; diff --git a/modules/debugging/bidInterceptor.js b/modules/debugging/bidInterceptor.js index 928fba3f10b..a6b452d2d91 100644 --- a/modules/debugging/bidInterceptor.js +++ b/modules/debugging/bidInterceptor.js @@ -4,11 +4,11 @@ import makeResponseResolvers from './responses.js'; * @typedef {Number|String|boolean|null|undefined} Scalar */ -export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { - const {deepAccess, deepClone, delayExecution, hasNonSerializableProperty, mergeDeep} = utils; - const responseResolvers = makeResponseResolvers({Renderer, BANNER, NATIVE, VIDEO}); +export function makebidInterceptor({ utils, BANNER, NATIVE, VIDEO, Renderer }) { + const { deepAccess, deepClone, delayExecution, hasNonSerializableProperty, mergeDeep } = utils; + const responseResolvers = makeResponseResolvers({ Renderer, BANNER, NATIVE, VIDEO }); function BidInterceptor(opts = {}) { - ({setTimeout: this.setTimeout = window.setTimeout.bind(window)} = opts); + ({ setTimeout: this.setTimeout = window.setTimeout.bind(window) } = opts); this.logger = opts.logger; this.rules = []; } @@ -78,7 +78,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { this.logger.logError(`Invalid 'when' definition for debug bid interceptor (in rule #${ruleNo})`); return () => false; } - function matches(candidate, {ref = matchDef, args = []}) { + function matches(candidate, { ref = matchDef, args = [] }) { return Object.entries(ref).map(([key, val]) => { const cVal = candidate[key]; if (val instanceof RegExp) { @@ -88,12 +88,12 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { return !!val(cVal, ...args); } if (typeof val === 'object') { - return matches(cVal, {ref: val, args}); + return matches(cVal, { ref: val, args }); } return cVal === val; }).every((i) => i); } - return (candidate, ...args) => matches(candidate, {args}); + return (candidate, ...args) => matches(candidate, { args }); }, /** * @typedef {Function} ReplacerFn @@ -116,18 +116,18 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { replDef = replDef || {}; let replFn; if (typeof replDef === 'function') { - replFn = ({args}) => replDef(...args); + replFn = ({ args }) => replDef(...args); } else if (typeof replDef !== 'object') { this.logger.logError(`Invalid 'then' definition for debug bid interceptor (in rule #${ruleNo})`); replFn = () => ({}); } else { - replFn = ({args, ref = replDef}) => { + replFn = ({ args, ref = replDef }) => { const result = Array.isArray(ref) ? [] : {}; Object.entries(ref).forEach(([key, val]) => { if (typeof val === 'function') { result[key] = val(...args); } else if (val != null && typeof val === 'object') { - result[key] = replFn({args, ref: val}) + result[key] = replFn({ args, ref: val }) } else { result[key] = val; } @@ -137,7 +137,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { } return (bid, ...args) => { const response = this.responseDefaults(bid); - mergeDeep(response, replFn({args: [bid, ...args]})); + mergeDeep(response, replFn({ args: [bid, ...args] })); const resolver = responseResolvers[response.mediaType]; resolver && resolver(bid, response); response.isDebug = true; @@ -149,7 +149,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { function wrap(configs = []) { return configs.map(config => { return Object.keys(config).some(k => !['config', 'igb'].includes(k)) - ? {config} + ? { config } : config }); } @@ -210,7 +210,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { bids.forEach((bid) => { const rule = this.match(bid, bidRequest); if (rule != null) { - matches.push({rule: rule, bid: bid}); + matches.push({ rule: rule, bid: bid }); } else { remainder.push(bid); } @@ -229,7 +229,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { * returns {{bids: {}[], bidRequest: {}} remaining bids that did not match any rule (this applies also to * bidRequest.bids) */ - intercept({bids, bidRequest, addBid, addPaapiConfig, done}) { + intercept({ bids, bidRequest, addBid, addPaapiConfig, done }) { if (bids == null) { bids = bidRequest.bids; } @@ -252,7 +252,7 @@ export function makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}) { } else { this.setTimeout(done, 0); } - return {bids, bidRequest}; + return { bids, bidRequest }; } }); return BidInterceptor; diff --git a/modules/debugging/debugging.js b/modules/debugging/debugging.js index d5bbc895ae1..5413ca37082 100644 --- a/modules/debugging/debugging.js +++ b/modules/debugging/debugging.js @@ -1,29 +1,29 @@ -import {makebidInterceptor} from './bidInterceptor.js'; -import {makePbsInterceptor} from './pbsInterceptor.js'; -import {addHooks, removeHooks} from './legacy.js'; +import { makebidInterceptor } from './bidInterceptor.js'; +import { makePbsInterceptor } from './pbsInterceptor.js'; +import { addHooks, removeHooks } from './legacy.js'; const interceptorHooks = []; let bidInterceptor; let enabled = false; -function enableDebugging(debugConfig, {fromSession = false, config, hook, logger}) { - config.setConfig({debug: true}); +function enableDebugging(debugConfig, { fromSession = false, config, hook, logger }) { + config.setConfig({ debug: true }); bidInterceptor.updateConfig(debugConfig); resetHooks(true); // also enable "legacy" overrides - removeHooks({hook}); - addHooks(debugConfig, {hook, logger}); + removeHooks({ hook }); + addHooks(debugConfig, { hook, logger }); if (!enabled) { enabled = true; logger.logMessage(`Debug overrides enabled${fromSession ? ' from session' : ''}`); } } -export function disableDebugging({hook, logger}) { +export function disableDebugging({ hook, logger }) { bidInterceptor.updateConfig(({})); resetHooks(false); // also disable "legacy" overrides - removeHooks({hook}); + removeHooks({ hook }); if (enabled) { enabled = false; logger.logMessage('Debug overrides disabled'); @@ -31,8 +31,8 @@ export function disableDebugging({hook, logger}) { } // eslint-disable-next-line no-restricted-properties -function saveDebuggingConfig(debugConfig, {sessionStorage = window.sessionStorage, DEBUG_KEY, utils} = {}) { - const {deepClone} = utils; +function saveDebuggingConfig(debugConfig, { sessionStorage = window.sessionStorage, DEBUG_KEY, utils } = {}) { + const { deepClone } = utils; if (!debugConfig.enabled) { try { sessionStorage.removeItem(DEBUG_KEY); @@ -51,7 +51,7 @@ function saveDebuggingConfig(debugConfig, {sessionStorage = window.sessionStorag } // eslint-disable-next-line no-restricted-properties -export function getConfig(debugging, {getStorage = () => window.sessionStorage, DEBUG_KEY, config, hook, logger, utils} = {}) { +export function getConfig(debugging, { getStorage = () => window.sessionStorage, DEBUG_KEY, config, hook, logger, utils } = {}) { if (debugging == null) return; let sessionStorage; try { @@ -60,16 +60,16 @@ export function getConfig(debugging, {getStorage = () => window.sessionStorage, logger.logError(`sessionStorage is not available: debugging configuration will not persist on page reload`, e); } if (sessionStorage != null) { - saveDebuggingConfig(debugging, {sessionStorage, DEBUG_KEY, utils}); + saveDebuggingConfig(debugging, { sessionStorage, DEBUG_KEY, utils }); } if (!debugging.enabled) { - disableDebugging({hook, logger}); + disableDebugging({ hook, logger }); } else { - enableDebugging(debugging, {config, hook, logger}); + enableDebugging(debugging, { config, hook, logger }); } } -export function sessionLoader({DEBUG_KEY, storage, config, hook, logger}) { +export function sessionLoader({ DEBUG_KEY, storage, config, hook, logger }) { let overrides; try { // eslint-disable-next-line no-restricted-properties @@ -78,13 +78,13 @@ export function sessionLoader({DEBUG_KEY, storage, config, hook, logger}) { } catch (e) { } if (overrides) { - enableDebugging(overrides, {fromSession: true, config, hook, logger}); + enableDebugging(overrides, { fromSession: true, config, hook, logger }); } } function resetHooks(enable) { interceptorHooks.forEach(([getHookFn, interceptor]) => { - getHookFn().getHooks({hook: interceptor}).remove(); + getHookFn().getHooks({ hook: interceptor }).remove(); }); if (enable) { interceptorHooks.forEach(([getHookFn, interceptor]) => { @@ -100,32 +100,32 @@ function registerBidInterceptor(getHookFn, interceptor) { }]); } -export function makeBidderBidInterceptor({utils}) { - const {delayExecution} = utils; +export function makeBidderBidInterceptor({ utils }) { + const { delayExecution } = utils; return function bidderBidInterceptor(next, interceptBids, spec, bids, bidRequest, ajax, wrapCallback, cbs) { const done = delayExecution(cbs.onCompletion, 2); - ({bids, bidRequest} = interceptBids({ + ({ bids, bidRequest } = interceptBids({ bids, bidRequest, addBid: wrapCallback(cbs.onBid), - addPaapiConfig: wrapCallback((config, bidRequest) => cbs.onPaapi({bidId: bidRequest.bidId, ...config})), + addPaapiConfig: wrapCallback((config, bidRequest) => cbs.onPaapi({ bidId: bidRequest.bidId, ...config })), done })); if (bids.length === 0) { cbs.onResponse?.({}); // trigger onResponse so that the bidder may be marked as "timely" if necessary done(); } else { - next(spec, bids, bidRequest, ajax, wrapCallback, {...cbs, onCompletion: done}); + next(spec, bids, bidRequest, ajax, wrapCallback, { ...cbs, onCompletion: done }); } } } -export function install({DEBUG_KEY, config, hook, createBid, logger, utils, BANNER, NATIVE, VIDEO, Renderer}) { - const BidInterceptor = makebidInterceptor({utils, BANNER, NATIVE, VIDEO, Renderer}); - bidInterceptor = new BidInterceptor({logger}); - const pbsBidInterceptor = makePbsInterceptor({createBid, utils}); - registerBidInterceptor(() => hook.get('processBidderRequests'), makeBidderBidInterceptor({utils})); +export function install({ DEBUG_KEY, config, hook, createBid, logger, utils, BANNER, NATIVE, VIDEO, Renderer }) { + const BidInterceptor = makebidInterceptor({ utils, BANNER, NATIVE, VIDEO, Renderer }); + bidInterceptor = new BidInterceptor({ logger }); + const pbsBidInterceptor = makePbsInterceptor({ createBid, utils }); + registerBidInterceptor(() => hook.get('processBidderRequests'), makeBidderBidInterceptor({ utils })); registerBidInterceptor(() => hook.get('processPBSRequest'), pbsBidInterceptor); - sessionLoader({DEBUG_KEY, config, hook, logger}); - config.getConfig('debugging', ({debugging}) => getConfig(debugging, {DEBUG_KEY, config, hook, logger, utils}), {init: true}); + sessionLoader({ DEBUG_KEY, config, hook, logger }); + config.getConfig('debugging', ({ debugging }) => getConfig(debugging, { DEBUG_KEY, config, hook, logger, utils }), { init: true }); } diff --git a/modules/debugging/index.js b/modules/debugging/index.js index 728c3841687..87d80ddc291 100644 --- a/modules/debugging/index.js +++ b/modules/debugging/index.js @@ -1,14 +1,14 @@ /* eslint prebid/validate-imports: 0 */ -import {config} from '../../src/config.js'; -import {hook} from '../../src/hook.js'; -import {install} from './debugging.js'; -import {prefixLog} from '../../src/utils.js'; -import {createBid} from '../../src/bidfactory.js'; -import {DEBUG_KEY} from '../../src/debugging.js'; +import { config } from '../../src/config.js'; +import { hook } from '../../src/hook.js'; +import { install } from './debugging.js'; +import { prefixLog } from '../../src/utils.js'; +import { createBid } from '../../src/bidfactory.js'; +import { DEBUG_KEY } from '../../src/debugging.js'; import * as utils from '../../src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../../src/mediaTypes.js'; -import {Renderer} from '../../src/Renderer.js'; +import { BANNER, NATIVE, VIDEO } from '../../src/mediaTypes.js'; +import { Renderer } from '../../src/Renderer.js'; install({ DEBUG_KEY, diff --git a/modules/debugging/legacy.js b/modules/debugging/legacy.js index e83b99c5194..9550e7a744b 100644 --- a/modules/debugging/legacy.js +++ b/modules/debugging/legacy.js @@ -1,17 +1,17 @@ export let addBidResponseBound; export let addBidderRequestsBound; -export function addHooks(overrides, {hook, logger}) { - addBidResponseBound = addBidResponseHook.bind({overrides, logger}); +export function addHooks(overrides, { hook, logger }) { + addBidResponseBound = addBidResponseHook.bind({ overrides, logger }); hook.get('addBidResponse').before(addBidResponseBound, 5); - addBidderRequestsBound = addBidderRequestsHook.bind({overrides, logger}); + addBidderRequestsBound = addBidderRequestsHook.bind({ overrides, logger }); hook.get('addBidderRequests').before(addBidderRequestsBound, 5); } -export function removeHooks({hook}) { - hook.get('addBidResponse').getHooks({hook: addBidResponseBound}).remove(); - hook.get('addBidderRequests').getHooks({hook: addBidderRequestsBound}).remove(); +export function removeHooks({ hook }) { + hook.get('addBidResponse').getHooks({ hook: addBidResponseBound }).remove(); + hook.get('addBidderRequests').getHooks({ hook: addBidderRequestsBound }).remove(); } /** @@ -55,7 +55,7 @@ export function applyBidOverrides(overrideObj, bidObj, bidType, logger) { } export function addBidResponseHook(next, adUnitCode, bid, reject) { - const {overrides, logger} = this; + const { overrides, logger } = this; if (bidderExcluded(overrides.bidders, bid.bidderCode)) { logger.logWarn(`bidder '${bid.bidderCode}' excluded from auction by bidder overrides`); @@ -74,7 +74,7 @@ export function addBidResponseHook(next, adUnitCode, bid, reject) { } export function addBidderRequestsHook(next, bidderRequests) { - const {overrides, logger} = this; + const { overrides, logger } = this; const includedBidderRequests = bidderRequests.filter(function (bidderRequest) { if (bidderExcluded(overrides.bidders, bidderRequest.bidderCode)) { diff --git a/modules/debugging/pbsInterceptor.js b/modules/debugging/pbsInterceptor.js index 753f502002d..484e99dcd5f 100644 --- a/modules/debugging/pbsInterceptor.js +++ b/modules/debugging/pbsInterceptor.js @@ -1,5 +1,5 @@ -export function makePbsInterceptor({createBid, utils}) { - const {deepClone, delayExecution} = utils; +export function makePbsInterceptor({ createBid, utils }) { + const { deepClone, delayExecution } = utils; return function pbsBidInterceptor(next, interceptBids, s2sBidRequest, bidRequests, ajax, { onResponse, onError, @@ -15,7 +15,7 @@ export function makePbsInterceptor({createBid, utils}) { function addBid(bid, bidRequest) { onBid({ adUnit: bidRequest.adUnitCode, - bid: Object.assign(createBid(bidRequest), {requestBidder: bidRequest.bidder}, bid) + bid: Object.assign(createBid(bidRequest), { requestBidder: bidRequest.bidder }, bid) }) } bidRequests = bidRequests @@ -42,7 +42,7 @@ export function makePbsInterceptor({createBid, utils}) { unit.bids = unit.bids.filter((bid) => bidIds.has(bid.bid_id)); }) s2sBidRequest.ad_units = s2sBidRequest.ad_units.filter((unit) => unit.bids.length > 0); - next(s2sBidRequest, bidRequests, ajax, {onResponse: signalResponse, onError, onBid}); + next(s2sBidRequest, bidRequests, ajax, { onResponse: signalResponse, onError, onBid }); } else { signalResponse(true, []); } diff --git a/modules/debugging/responses.js b/modules/debugging/responses.js index d30ffdeb8d7..dde386934d1 100644 --- a/modules/debugging/responses.js +++ b/modules/debugging/responses.js @@ -7,7 +7,7 @@ function getSlotDivid(adUnitCode) { return slot?.getSlotElementId(); } -export default function ({Renderer, BANNER, NATIVE, VIDEO}) { +export default function ({ Renderer, BANNER, NATIVE, VIDEO }) { return { [BANNER]: (bid, bidResponse) => { if (!bidResponse.hasOwnProperty('ad') && !bidResponse.hasOwnProperty('adUrl')) { diff --git a/modules/debugging/standalone.js b/modules/debugging/standalone.js index b3b539f5aa2..f715a60ccc4 100644 --- a/modules/debugging/standalone.js +++ b/modules/debugging/standalone.js @@ -1,4 +1,4 @@ -import {install} from './debugging.js'; +import { install } from './debugging.js'; window._pbjsGlobals.forEach((name) => { if (window[name] && window[name]._installDebugging === true) { diff --git a/modules/deepintentBidAdapter.js b/modules/deepintentBidAdapter.js index c5acc942218..280b6f735c0 100644 --- a/modules/deepintentBidAdapter.js +++ b/modules/deepintentBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { generateUUID, deepSetValue, deepAccess, isArray, isFn, isPlainObject, logError, logWarn } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; diff --git a/modules/deepintentDpesIdSystem.js b/modules/deepintentDpesIdSystem.js index a1f1e29a4ce..90baadee34c 100644 --- a/modules/deepintentDpesIdSystem.js +++ b/modules/deepintentDpesIdSystem.js @@ -6,9 +6,9 @@ */ import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; -import {isPlainObject} from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { isPlainObject } from '../src/utils.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -17,7 +17,7 @@ import {isPlainObject} from '../src/utils.js'; */ const MODULE_NAME = 'deepintentId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** @type {Submodule} */ export const deepintentDpesSubmodule = { diff --git a/modules/defineMediaBidAdapter.js b/modules/defineMediaBidAdapter.js index 937ad9fb8d8..3ec6cf4f8cc 100644 --- a/modules/defineMediaBidAdapter.js +++ b/modules/defineMediaBidAdapter.js @@ -9,10 +9,10 @@ * @version 1.0.0 */ -import {logInfo, logError, logWarn } from "../src/utils.js"; +import { logInfo, logError, logWarn } from "../src/utils.js"; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { ajax } from '../src/ajax.js'; // Bidder identification and compliance constants @@ -181,7 +181,7 @@ export const spec = { try { // Use the converter from the request if available (with custom TTL), otherwise use default const responseConverter = request.converter || converter; - const bids = responseConverter.fromORTB({response: serverResponse.body, request: request.data}).bids; + const bids = responseConverter.fromORTB({ response: serverResponse.body, request: request.data }).bids; logInfo(`[${BIDDER_CODE}] Successfully parsed ${bids.length} bids`); return bids; } catch (error) { diff --git a/modules/deltaprojectsBidAdapter.js b/modules/deltaprojectsBidAdapter.js index 1a9f2b46b9e..0904c018d31 100644 --- a/modules/deltaprojectsBidAdapter.js +++ b/modules/deltaprojectsBidAdapter.js @@ -227,7 +227,7 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent) { export function getBidFloor(bid, mediaType, size, currency) { if (isFn(bid.getFloor)) { const bidFloorCurrency = currency || 'USD'; - const bidFloor = bid.getFloor({currency: bidFloorCurrency, mediaType: mediaType, size: size}); + const bidFloor = bid.getFloor({ currency: bidFloorCurrency, mediaType: mediaType, size: size }); if (isNumber(bidFloor?.floor)) { return bidFloor; } diff --git a/modules/dfpAdServerVideo.js b/modules/dfpAdServerVideo.js index a7053622102..d9e038d58d2 100644 --- a/modules/dfpAdServerVideo.js +++ b/modules/dfpAdServerVideo.js @@ -1,6 +1,6 @@ /* eslint prebid/validate-imports: "off" */ -import {registerVideoSupport} from '../src/adServerManager.js'; -import {buildGamVideoUrl, getVastXml, notifyTranslationModule, dep, VAST_TAG_URI_TAGNAME, getBase64BlobContent} from './gamAdServerVideo.js'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { buildGamVideoUrl, getVastXml, notifyTranslationModule, dep, VAST_TAG_URI_TAGNAME, getBase64BlobContent } from './gamAdServerVideo.js'; export const buildDfpVideoUrl = buildGamVideoUrl; export { getVastXml, notifyTranslationModule, dep, VAST_TAG_URI_TAGNAME, getBase64BlobContent }; diff --git a/modules/dfpAdpod.js b/modules/dfpAdpod.js index 831507dcc5c..4f547ececfa 100644 --- a/modules/dfpAdpod.js +++ b/modules/dfpAdpod.js @@ -1,6 +1,6 @@ /* eslint prebid/validate-imports: "off" */ -import {registerVideoSupport} from '../src/adServerManager.js'; -import {buildAdpodVideoUrl, adpodUtils} from './gamAdpod.js'; +import { registerVideoSupport } from '../src/adServerManager.js'; +import { buildAdpodVideoUrl, adpodUtils } from './gamAdpod.js'; export { buildAdpodVideoUrl, adpodUtils }; diff --git a/modules/dianomiBidAdapter.js b/modules/dianomiBidAdapter.js index 55ee192461f..1d369800adf 100644 --- a/modules/dianomiBidAdapter.js +++ b/modules/dianomiBidAdapter.js @@ -17,7 +17,7 @@ import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; -import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js'; +import { getUserSyncParams } from '../libraries/userSyncUtils/userSyncUtils.js'; const { getConfig } = config; diff --git a/modules/digitalMatterBidAdapter.js b/modules/digitalMatterBidAdapter.js index 37c01e6a9d9..704069783bc 100644 --- a/modules/digitalMatterBidAdapter.js +++ b/modules/digitalMatterBidAdapter.js @@ -1,9 +1,9 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {deepAccess, deepSetValue, getWinDimensions, inIframe, logWarn, parseSizesInput} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { deepAccess, deepSetValue, getWinDimensions, inIframe, logWarn, parseSizesInput } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const BIDDER_CODE = 'digitalMatter'; const GVLID = 1345; @@ -30,7 +30,7 @@ export const spec = { const common = bidderRequest.ortb2 || {}; const site = common.site; const tid = common?.source?.tid; - const {user} = common || {}; + const { user } = common || {}; if (!site.page) { site.page = bidderRequest.refererInfo.page; @@ -43,7 +43,7 @@ export const spec = { const cur = currency && [currency]; const imp = validBidRequests.map((bid, id) => { - const {accountId, siteId} = bid.params; + const { accountId, siteId } = bid.params; const bannerParams = deepAccess(bid, 'mediaTypes.banner'); const position = deepAccess(bid, 'mediaTypes.banner.pos') ?? 0; @@ -110,7 +110,7 @@ export const spec = { }, interpretResponse: function (serverResponse) { const body = serverResponse.body || serverResponse; - const {cur} = body; + const { cur } = body; const bids = []; if (body && body.bids && Array.isArray(body.bids)) { @@ -162,9 +162,9 @@ export const spec = { if (url) { if ((type === 'image' || type === 'redirect') && syncOptions.pixelEnabled) { - userSyncs.push({type: 'image', url: url}); + userSyncs.push({ type: 'image', url: url }); } else if (type === 'iframe' && syncOptions.iframeEnabled) { - userSyncs.push({type: 'iframe', url: url}); + userSyncs.push({ type: 'iframe', url: url }); } } }) diff --git a/modules/digitalcaramelBidAdapter.js b/modules/digitalcaramelBidAdapter.js index 1f045fb352d..8b724ae6515 100644 --- a/modules/digitalcaramelBidAdapter.js +++ b/modules/digitalcaramelBidAdapter.js @@ -14,8 +14,8 @@ export const spec = { isBidRequestValid: sspValidRequest, buildRequests: sspBuildRequests(DEFAULT_ENDPOINT), interpretResponse: sspInterpretResponse(TIME_TO_LIVE, ADOMAIN), - getUserSyncs: getUserSyncs(SYNC_ENDPOINT, {usp: 'usp', consent: 'consent'}), - supportedMediaTypes: [ BANNER, VIDEO ] + getUserSyncs: getUserSyncs(SYNC_ENDPOINT, { usp: 'usp', consent: 'consent' }), + supportedMediaTypes: [BANNER, VIDEO] } registerBidder(spec); diff --git a/modules/discoveryBidAdapter.js b/modules/discoveryBidAdapter.js index 8992efa9829..ba2147e6412 100644 --- a/modules/discoveryBidAdapter.js +++ b/modules/discoveryBidAdapter.js @@ -18,7 +18,7 @@ import { cookieSync } from '../libraries/cookieSync/cookieSync.js'; const BIDDER_CODE = 'discovery'; const ENDPOINT_URL = 'https://rtb-jp.mediago.io/api/bid?tn='; const TIME_TO_LIVE = 500; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const globals = {}; const itemMaps = {}; const MEDIATYPE = [BANNER, NATIVE]; diff --git a/modules/displayioBidAdapter.js b/modules/displayioBidAdapter.js index 69ff56621fd..66b4716dee7 100644 --- a/modules/displayioBidAdapter.js +++ b/modules/displayioBidAdapter.js @@ -1,10 +1,10 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {logWarn} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { logWarn } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getAllOrtbKeywords } from '../libraries/keywords/keywords.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; const ADAPTER_VERSION = '1.1.0'; @@ -28,7 +28,7 @@ export const spec = { const data = getPayload(bid, bidderRequest); return { method: 'POST', - headers: {'Content-Type': 'application/json;charset=utf-8'}, + headers: { 'Content-Type': 'application/json;charset=utf-8' }, url, data }; @@ -72,7 +72,7 @@ export const spec = { function getPayload (bid, bidderRequest) { const connection = getConnectionInfo(); - const storage = getStorageManager({bidderCode: BIDDER_CODE}); + const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const userSession = (() => { let us = storage.getDataFromLocalStorage(US_KEY); if (!us) { @@ -88,7 +88,7 @@ function getPayload (bid, bidderRequest) { const { params, adUnitCode, bidId } = bid; const { siteId, placementId, renderURL, pageCategory, keywords } = params; const { refererInfo, uspConsent, gdprConsent } = bidderRequest; - const mediation = {gdprConsent: '', gdpr: '-1'}; + const mediation = { gdprConsent: '', gdpr: '-1' }; if (gdprConsent && 'gdprApplies' in gdprConsent) { if (gdprConsent.consentString !== undefined) { mediation.gdprConsent = gdprConsent.consentString; diff --git a/modules/distroscaleBidAdapter.js b/modules/distroscaleBidAdapter.js index 4737c8bf969..02982b27a82 100644 --- a/modules/distroscaleBidAdapter.js +++ b/modules/distroscaleBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { logWarn, isPlainObject, isStr, isArray, isFn, inIframe, mergeDeep, deepSetValue, logError, deepClone } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; @@ -12,7 +12,7 @@ const AUCTION_TYPE = 1; const GVLID = 754; const UNDEF = undefined; -const SUPPORTED_MEDIATYPES = [ BANNER ]; +const SUPPORTED_MEDIATYPES = [BANNER]; function _getHost(url) { const a = document.createElement('a'); @@ -222,10 +222,10 @@ export const spec = { // First Party Data const commonFpd = bidderRequest.ortb2 || {}; if (commonFpd.site) { - mergeDeep(payload, {site: commonFpd.site}); + mergeDeep(payload, { site: commonFpd.site }); } if (commonFpd.user) { - mergeDeep(payload, {user: commonFpd.user}); + mergeDeep(payload, { user: commonFpd.user }); } // User IDs diff --git a/modules/djaxBidAdapter.js b/modules/djaxBidAdapter.js index 775ae146b88..15ba614f449 100644 --- a/modules/djaxBidAdapter.js +++ b/modules/djaxBidAdapter.js @@ -1,8 +1,8 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { ajax } from '../src/ajax.js'; -import {Renderer} from '../src/Renderer.js'; +import { Renderer } from '../src/Renderer.js'; const SUPPORTED_AD_TYPES = [BANNER, VIDEO]; const BIDDER_CODE = 'djax'; @@ -30,7 +30,7 @@ function createRenderer(bidAd, rendererParams, adUnitCode) { id: rendererParams.id, url: rendererParams.url, loaded: false, - config: {'player_height': bidAd.height, 'player_width': bidAd.width}, + config: { 'player_height': bidAd.height, 'player_width': bidAd.width }, adUnitCode }); try { diff --git a/modules/docereeBidAdapter.js b/modules/docereeBidAdapter.js index 849aa73bde6..c21a18edd36 100644 --- a/modules/docereeBidAdapter.js +++ b/modules/docereeBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { triggerPixel } from '../src/utils.js'; import { config } from '../src/config.js'; import { BANNER } from '../src/mediaTypes.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const BIDDER_CODE = 'doceree'; const GVLID = 1063; const END_POINT = 'https://bidder.doceree.com' @@ -12,7 +12,7 @@ export const spec = { code: BIDDER_CODE, gvlid: GVLID, url: '', - supportedMediaTypes: [ BANNER ], + supportedMediaTypes: [BANNER], isBidRequestValid: (bid) => { const { placementId } = bid.params; diff --git a/modules/dpaiBidAdapter.js b/modules/dpaiBidAdapter.js new file mode 100644 index 00000000000..4cf359b196b --- /dev/null +++ b/modules/dpaiBidAdapter.js @@ -0,0 +1,19 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'dpai'; +const AD_URL = 'https://ssp.drift-pixel.ai/pbjs'; +const SYNC_URL = 'https://sync.drift-pixel.ai'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse, + getUserSyncs: getUserSyncs(SYNC_URL) +}; + +registerBidder(spec); diff --git a/modules/dpaiBidAdapter.md b/modules/dpaiBidAdapter.md new file mode 100644 index 00000000000..4882abdacc4 --- /dev/null +++ b/modules/dpaiBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: DPAI Bidder Adapter +Module Type: DPAI Bidder Adapter +Maintainer: adops@driftpixel.ai +``` + +# Description + +Connects to DPAI exchange for bids. +DPAI bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'dpai', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'dpai', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'dpai', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` diff --git a/modules/driftpixelBidAdapter.js b/modules/driftpixelBidAdapter.js index 5dd0d3a5835..78c23c75cf6 100644 --- a/modules/driftpixelBidAdapter.js +++ b/modules/driftpixelBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; const BIDDER_CODE = 'driftpixel'; const ENDPOINT = 'https://pbjs.driftpixel.live'; diff --git a/modules/dsaControl.js b/modules/dsaControl.js index 73a1dd19cd4..bb87ef7ad3f 100644 --- a/modules/dsaControl.js +++ b/modules/dsaControl.js @@ -1,9 +1,9 @@ -import {config} from '../src/config.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {timedBidResponseHook} from '../src/utils/perfMetrics.js'; +import { config } from '../src/config.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { timedBidResponseHook } from '../src/utils/perfMetrics.js'; import { REJECTION_REASON } from '../src/constants.js'; -import {getHook} from '../src/hook.js'; -import {logInfo, logWarn} from '../src/utils.js'; +import { getHook } from '../src/hook.js'; +import { logInfo, logWarn } from '../src/utils.js'; let expiryHandle; let dsaAuctions = {}; @@ -48,7 +48,7 @@ function toggleHooks(enabled) { }); logInfo('dsaControl: DSA bid validation is enabled') } else if (!enabled && expiryHandle != null) { - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); + getHook('addBidResponse').getHooks({ hook: addBidResponseHook }).remove(); expiryHandle(); expiryHandle = null; logInfo('dsaControl: DSA bid validation is disabled') diff --git a/modules/dspxBidAdapter.js b/modules/dspxBidAdapter.js index 19419ba70e8..e6bc012374f 100644 --- a/modules/dspxBidAdapter.js +++ b/modules/dspxBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, logMessage, getBidIdParameter, logError, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { deepAccess, logMessage, getBidIdParameter, logError, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { fillUsersIds, @@ -16,7 +16,7 @@ import { extractUserSegments, interpretResponse } from '../libraries/dspxUtils/bidderUtils.js'; -import {Renderer} from '../src/Renderer.js'; +import { Renderer } from '../src/Renderer.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/dvgroupBidAdapter.js b/modules/dvgroupBidAdapter.js index bf63dd0bbe0..fce3dfd3396 100644 --- a/modules/dvgroupBidAdapter.js +++ b/modules/dvgroupBidAdapter.js @@ -1,7 +1,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { hasPurpose1Consent } from '../src/utils/gdpr.js'; -import {deepAccess, deepClone, replaceAuctionPrice} from '../src/utils.js'; +import { deepAccess, deepClone, replaceAuctionPrice } from '../src/utils.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const BIDDER_CODE = 'dvgroup'; @@ -57,7 +57,7 @@ export const spec = { return []; } - const bids = converter.fromORTB({response: response.body, request: request.data}).bids; + const bids = converter.fromORTB({ response: response.body, request: request.data }).bids; bids.forEach((bid) => { bid.meta = bid.meta || {}; bid.ttl = bid.ttl || TIME_TO_LIVE; @@ -92,7 +92,7 @@ export const spec = { return syncs; }, - supportedMediaTypes: [ BANNER, VIDEO ] + supportedMediaTypes: [BANNER, VIDEO] } registerBidder(spec); diff --git a/modules/dxkultureBidAdapter.js b/modules/dxkultureBidAdapter.js index 78b37a67602..0a1e3229d3e 100644 --- a/modules/dxkultureBidAdapter.js +++ b/modules/dxkultureBidAdapter.js @@ -7,10 +7,10 @@ import { deepSetValue, mergeDeep } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { Renderer } from '../src/Renderer.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { ortbConverter } from '../libraries/ortbConverter/converter.js' /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -62,7 +62,7 @@ const converter = ortbConverter({ }, bidResponse(buildBidResponse, bid, context) { let resMediaType; - const {bidRequest} = context; + const { bidRequest } = context; if (bid.adm?.trim().startsWith(' !enabled).map(({name}) => name)); + const bannedModules = new Set(modules.filter(({ enabled }) => !enabled).map(({ name }) => name)); if (bannedModules.size) { const init = suppression === suppressionMethod.SUBMODULES; rules.push(registerActivityControl(ACTIVITY_ENRICH_EIDS, MODULE_NAME, userIdSystemBlockRule(bannedModules, init))); } if (testRun) { - setAnalyticLabels({[testRun]: modules}); + setAnalyticLabels({ [testRun]: modules }); } } @@ -61,10 +61,10 @@ export function reset() { } export function compareConfigs(old, current) { - const {modules: newModules, testRun: newTestRun} = current; - const {modules: oldModules, testRun: oldTestRun} = old; + const { modules: newModules, testRun: newTestRun } = current; + const { modules: oldModules, testRun: oldTestRun } = old; - const getModulesObject = (modules) => modules.reduce((acc, curr) => ({...acc, [curr.name]: curr.percentage}), {}); + const getModulesObject = (modules) => modules.reduce((acc, curr) => ({ ...acc, [curr.name]: curr.percentage }), {}); const percentageEqual = deepEqual( getModulesObject(oldModules), @@ -78,16 +78,16 @@ export function compareConfigs(old, current) { function userIdSystemBlockRule(bannedModules, init) { return (params) => { if ((params.init ?? true) === init && params[ACTIVITY_PARAM_COMPONENT_TYPE] === MODULE_TYPE_UID && bannedModules.has(params[ACTIVITY_PARAM_COMPONENT_NAME])) { - return {allow: false, reason: 'disabled due to AB testing'}; + return { allow: false, reason: 'disabled due to AB testing' }; } } }; export function getCalculatedSubmodules(modules = moduleConfig.modules) { return (modules || []) - .map(({name, percentage}) => { + .map(({ name, percentage }) => { const enabled = Math.random() < percentage; - return {name, percentage, enabled} + return { name, percentage, enabled } }); }; @@ -120,7 +120,7 @@ export function storeTestConfig(testRun, modules, storeSplits, storageManager) { return; } - const configToStore = {testRun, modules}; + const configToStore = { testRun, modules }; storeMethod(STORAGE_KEY, JSON.stringify(configToStore)); logInfo(`${MODULE_NAME}: AB test config successfully saved to ${storeSplits} storage`); }; diff --git a/modules/eplanningBidAdapter.js b/modules/eplanningBidAdapter.js index 7ef55e31784..12e643402d6 100644 --- a/modules/eplanningBidAdapter.js +++ b/modules/eplanningBidAdapter.js @@ -1,14 +1,14 @@ -import {isEmpty, parseSizesInput, isGptPubadsDefined, getWinDimensions} from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; -import {serializeSupplyChain} from '../libraries/schainSerializer/schainSerializer.js'; +import { isEmpty, parseSizesInput, isGptPubadsDefined, getWinDimensions } from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { isSlotMatchingAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; +import { serializeSupplyChain } from '../libraries/schainSerializer/schainSerializer.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; const BIDDER_CODE = 'eplanning'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const rnd = Math.random(); const DEFAULT_SV = 'pbjs.e-planning.net'; const DEFAULT_ISV = 'i.e-planning.net'; @@ -298,7 +298,7 @@ function getSpaces(bidRequests, ml) { } const spacesStruct = getSpacesStruct(bidRequests); - const es = {str: '', vs: '', map: {}, impType: impType}; + const es = { str: '', vs: '', map: {}, impType: impType }; es.str = Object.keys(spacesStruct).map(size => spacesStruct[size].map((bid, i) => { es.vs += getVs(bid); diff --git a/modules/eskimiBidAdapter.js b/modules/eskimiBidAdapter.js index b345bf3b9af..118910827fd 100644 --- a/modules/eskimiBidAdapter.js +++ b/modules/eskimiBidAdapter.js @@ -1,8 +1,8 @@ -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; -import {getBidIdParameter, logInfo, mergeDeep} from '../src/utils.js'; +import { getBidIdParameter, logInfo, mergeDeep } from '../src/utils.js'; import { getTimeZone } from '../libraries/timezone/timezone.js'; /** @@ -66,7 +66,7 @@ export const spec = { onTimeout: function (timeoutData) { logInfo('Timeout: ', timeoutData); }, - onBidderError: function ({error, bidderRequest}) { + onBidderError: function ({ error, bidderRequest }) { logInfo('Error: ', error, bidderRequest); }, } @@ -158,14 +158,14 @@ function buildRequests(validBidRequests, bidderRequest) { } function interpretResponse(response, request) { - return CONVERTER.fromORTB({request: request.data, response: response.body}).bids; + return CONVERTER.fromORTB({ request: request.data, response: response.body }).bids; } function buildVideoImp(bidRequest, imp) { const videoAdUnitParams = utils.deepAccess(bidRequest, `mediaTypes.${VIDEO}`, {}); const videoBidderParams = utils.deepAccess(bidRequest, `params.${VIDEO}`, {}); - const videoParams = {...videoAdUnitParams, ...videoBidderParams}; + const videoParams = { ...videoAdUnitParams, ...videoBidderParams }; const videoSizes = (videoAdUnitParams && videoAdUnitParams.playerSize) || []; @@ -184,14 +184,14 @@ function buildVideoImp(bidRequest, imp) { imp.video.plcmt = imp.video.plcmt || 4; } - return {...imp}; + return { ...imp }; } function buildBannerImp(bidRequest, imp) { const bannerAdUnitParams = utils.deepAccess(bidRequest, `mediaTypes.${BANNER}`, {}); const bannerBidderParams = utils.deepAccess(bidRequest, `params.${BANNER}`, {}); - const bannerParams = {...bannerAdUnitParams, ...bannerBidderParams}; + const bannerParams = { ...bannerAdUnitParams, ...bannerBidderParams }; const sizes = bidRequest.mediaTypes.banner.sizes; @@ -206,15 +206,15 @@ function buildBannerImp(bidRequest, imp) { } }); - return {...imp}; + return { ...imp }; } function createRequest(bidRequests, bidderRequest, mediaType) { - const data = CONVERTER.toORTB({bidRequests, bidderRequest, context: {mediaType}}) + const data = CONVERTER.toORTB({ bidRequests, bidderRequest, context: { mediaType } }) const bid = bidRequests.find((b) => b.params.placementId) if (!data.site) data.site = {} - data.site.ext = {placementId: parseInt(bid.params.placementId)} + data.site.ext = { placementId: parseInt(bid.params.placementId) } if (bidderRequest.gdprConsent) { if (!data.user) data.user = {}; diff --git a/modules/etargetBidAdapter.js b/modules/etargetBidAdapter.js index 89ec415b173..0ce137e519c 100644 --- a/modules/etargetBidAdapter.js +++ b/modules/etargetBidAdapter.js @@ -1,5 +1,5 @@ import { deepClone, deepSetValue, isFn, isPlainObject } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'etarget'; @@ -21,7 +21,7 @@ const countryMap = { export const spec = { code: BIDDER_CODE, gvlid: GVL_ID, - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function (bid) { return !!(bid.params.refid && bid.params.country); }, diff --git a/modules/euidIdSystem.js b/modules/euidIdSystem.js index 9070c7efd3e..fb984a939ae 100644 --- a/modules/euidIdSystem.js +++ b/modules/euidIdSystem.js @@ -6,9 +6,9 @@ */ import { logInfo, logWarn, deepAccess } from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { Uid2GetId, Uid2CodeVersion, extractIdentityFromParams } from '../libraries/uid2IdSystemShared/uid2IdSystem_shared.js'; @@ -40,7 +40,7 @@ function createLogger(logger, prefix) { const _logInfo = createLogger(logInfo, LOG_PRE_FIX); const _logWarn = createLogger(logWarn, LOG_PRE_FIX); -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function hasWriteToDeviceConsent(consentData) { const gdprApplies = consentData?.gdprApplies === true; diff --git a/modules/excoBidAdapter.js b/modules/excoBidAdapter.js index 5123120be88..3b5d6d4bc93 100644 --- a/modules/excoBidAdapter.js +++ b/modules/excoBidAdapter.js @@ -45,7 +45,7 @@ export class AdapterHelpers { createSyncUrl({ consentString, gppString, applicableSections, gdprApplies }, network) { try { const url = new URL(SYNC_URL); - const networks = [ '368531133' ]; + const networks = ['368531133']; if (network) { networks.push(network); @@ -392,7 +392,7 @@ export const spec = { */ interpretResponse: function (response, request) { const body = response?.body?.Result || response?.body || {}; - const converted = converter.fromORTB({response: body, request: request?.data}); + const converted = converter.fromORTB({ response: body, request: request?.data }); const bids = converted.bids || []; if (bids.length && !EVENTS.subscribed) { diff --git a/modules/experianRtdProvider.js b/modules/experianRtdProvider.js index cd415d4b32c..7200081869a 100644 --- a/modules/experianRtdProvider.js +++ b/modules/experianRtdProvider.js @@ -96,10 +96,10 @@ export const experianRtdObj = { if (userConsent != null) { if (userConsent.gdpr != null) { const { gdprApplies, consentString } = userConsent.gdpr; - mergeDeep(queryObj, {gdpr: gdprApplies, gdpr_consent: consentString}) + mergeDeep(queryObj, { gdpr: gdprApplies, gdpr_consent: consentString }) } if (userConsent.uspConsent != null) { - mergeDeep(queryObj, {us_privacy: userConsent.uspConsent}) + mergeDeep(queryObj, { us_privacy: userConsent.uspConsent }) } } const consentQueryString = Object.entries(queryObj).map(([key, val]) => `${key}=${val}`).join('&'); diff --git a/modules/express.js b/modules/express.js index a2998baed07..760a6f578e5 100644 --- a/modules/express.js +++ b/modules/express.js @@ -1,5 +1,5 @@ import { logMessage, logWarn, logError, logInfo } from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { getGlobal } from '../src/prebidGlobal.js'; const MODULE_NAME = 'express'; const pbjsInstance = getGlobal(); diff --git a/modules/fabrickIdSystem.js b/modules/fabrickIdSystem.js index 34fa990c080..c946667fcc3 100644 --- a/modules/fabrickIdSystem.js +++ b/modules/fabrickIdSystem.js @@ -115,9 +115,9 @@ export const fabrickIdSubmodule = { callback(); } }; - ajax(url, callbacks, null, {method: 'GET', withCredentials: true}); + ajax(url, callbacks, null, { method: 'GET', withCredentials: true }); }; - return {callback: resp}; + return { callback: resp }; } catch (e) { logError(`fabrickIdSystem encountered an error`, e); } diff --git a/modules/fanBidAdapter.js b/modules/fanBidAdapter.js index 04247011751..d4b2954d9d2 100644 --- a/modules/fanBidAdapter.js +++ b/modules/fanBidAdapter.js @@ -19,7 +19,7 @@ const DEFAULT_ENDPOINT = NETWORK_ENDPOINTS['fan']; const DEFAULT_CURRENCY = 'USD'; const DEFAULT_TTL = 300; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const converter = ortbConverter({ context: { diff --git a/modules/feedadBidAdapter.js b/modules/feedadBidAdapter.js index e6200bb3561..b382d34082b 100644 --- a/modules/feedadBidAdapter.js +++ b/modules/feedadBidAdapter.js @@ -1,7 +1,7 @@ -import {deepAccess, isArray, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; +import { deepAccess, isArray, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -291,7 +291,7 @@ function createTrackingParams(data, klass) { if (!BID_METADATA.hasOwnProperty(bidId)) { return null; } - const {referer, transactionId} = BID_METADATA[bidId]; + const { referer, transactionId } = BID_METADATA[bidId]; delete BID_METADATA[bidId]; return { app_hybrid: false, diff --git a/modules/finativeBidAdapter.js b/modules/finativeBidAdapter.js index a1dbfb3ee0c..c744fc6b637 100644 --- a/modules/finativeBidAdapter.js +++ b/modules/finativeBidAdapter.js @@ -1,17 +1,17 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {NATIVE} from '../src/mediaTypes.js'; -import {_map, deepSetValue, isEmpty, setOnAny} from '../src/utils.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { NATIVE } from '../src/mediaTypes.js'; +import { _map, deepSetValue, isEmpty, setOnAny } from '../src/utils.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const BIDDER_CODE = 'finative'; const DEFAULT_CUR = 'EUR'; const ENDPOINT_URL = 'https://b.finative.cloud/cds/rtb/bid?format=openrtb2.5&ssp=pb'; -const NATIVE_ASSET_IDS = {0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon'}; +const NATIVE_ASSET_IDS = { 0: 'title', 1: 'body', 2: 'sponsoredBy', 3: 'image', 4: 'cta', 5: 'icon' }; const NATIVE_PARAMS = { title: { @@ -190,7 +190,7 @@ export const spec = { registerBidder(spec); function parseNative(bid) { - const {assets, link, imptrackers} = bid.adm.native; + const { assets, link, imptrackers } = bid.adm.native; const clickUrl = link.url.replace(/\$\{AUCTION_PRICE\}/g, bid.price); diff --git a/modules/fintezaAnalyticsAdapter.js b/modules/fintezaAnalyticsAdapter.js index 3f22fe444bd..71c74986a6f 100644 --- a/modules/fintezaAnalyticsAdapter.js +++ b/modules/fintezaAnalyticsAdapter.js @@ -2,12 +2,12 @@ import { parseUrl, logError } from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getStorageManager } from '../src/storageManager.js'; import { EVENTS } from '../src/constants.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'finteza'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); const ANALYTICS_TYPE = 'endpoint'; const FINTEZA_HOST = 'https://content.mql5.com/tr'; @@ -76,7 +76,7 @@ function initFirstVisit() { cookies = {}; } - visitDate = cookies[ FIRST_VISIT_DATE ]; + visitDate = cookies[FIRST_VISIT_DATE]; if (!visitDate) { now = new Date(); @@ -181,7 +181,7 @@ function initSession() { cookies = {}; } - sessionId = cookies[ SESSION_ID ]; + sessionId = cookies[SESSION_ID]; if (!sessionId || !checkSessionByExpires() || @@ -269,7 +269,7 @@ function getTrackRequestLastTime() { // TODO: commented out because of rule violations cookie = {} // parseCookies(document.cookie); - cookie = cookie[ TRACK_TIME_KEY ]; + cookie = cookie[TRACK_TIME_KEY]; if (cookie) { return parseInt(cookie, 10); } @@ -282,7 +282,7 @@ function getAntiCacheParam() { const date = new Date(); const rand = (Math.random() * 99999 + 1) >>> 0; - return ([ date.getTime(), rand ].join('')); + return ([date.getTime(), rand].join('')); } function replaceBidder(str, bidder) { diff --git a/modules/flippBidAdapter.js b/modules/flippBidAdapter.js index d1e8048be85..fc1d8eaa27e 100644 --- a/modules/flippBidAdapter.js +++ b/modules/flippBidAdapter.js @@ -1,7 +1,7 @@ -import {isEmpty, parseUrl} from '../src/utils.js'; +import { isEmpty, parseUrl } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getStorageManager } from '../src/storageManager.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -28,7 +28,7 @@ const COMPACT_DEFAULT_HEIGHT = 600; const STANDARD_DEFAULT_HEIGHT = 1800; let userKey = null; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function getUserKey(options = {}) { if (userKey) { @@ -127,9 +127,9 @@ export const spec = { siteId: bid.params.siteId, adTypes: getAdTypes(bid.params.creativeType), count: 1, - ...(!isEmpty(bid.params.zoneIds) && {zoneIds: bid.params.zoneIds}), + ...(!isEmpty(bid.params.zoneIds) && { zoneIds: bid.params.zoneIds }), properties: { - ...(!isEmpty(contentCode) && {contentCode: contentCode.slice(0, 32)}), + ...(!isEmpty(contentCode) && { contentCode: contentCode.slice(0, 32) }), }, options, prebid: { diff --git a/modules/floxisBidAdapter.js b/modules/floxisBidAdapter.js new file mode 100644 index 00000000000..c677f054a46 --- /dev/null +++ b/modules/floxisBidAdapter.js @@ -0,0 +1,149 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { triggerPixel, mergeDeep } from '../src/utils.js'; + +const BIDDER_CODE = 'floxis'; +const DEFAULT_BID_TTL = 300; +const DEFAULT_CURRENCY = 'USD'; +const DEFAULT_NET_REVENUE = true; +const DEFAULT_REGION = 'us-e'; +const DEFAULT_PARTNER = BIDDER_CODE; +const PARTNER_REGION_WHITELIST = { + [DEFAULT_PARTNER]: [DEFAULT_REGION], +}; + +function isAllowedPartnerRegion(partner, region) { + return PARTNER_REGION_WHITELIST[partner]?.includes(region) || false; +} + +function getEndpointUrl(seat, region, partner) { + if (!isAllowedPartnerRegion(partner, region)) return null; + const host = partner === BIDDER_CODE + ? `${region}.floxis.tech` + : `${partner}-${region}.floxis.tech`; + return `https://${host}/pbjs?seat=${encodeURIComponent(seat)}`; +} + +function normalizeBidParams(params = {}) { + return { + seat: params.seat, + region: params.region ?? DEFAULT_REGION, + partner: params.partner ?? DEFAULT_PARTNER + }; +} + +const CONVERTER = ortbConverter({ + context: { + netRevenue: DEFAULT_NET_REVENUE, + ttl: DEFAULT_BID_TTL, + currency: DEFAULT_CURRENCY + }, + imp(buildImp, bidRequest, context) { + const imp = buildImp(bidRequest, context); + imp.secure = bidRequest.ortb2Imp?.secure ?? 1; + + let floorInfo; + if (typeof bidRequest.getFloor === 'function') { + try { + floorInfo = bidRequest.getFloor({ + currency: DEFAULT_CURRENCY, + mediaType: '*', + size: '*' + }); + } catch (e) { } + } + const floor = floorInfo?.floor; + const floorCur = floorInfo?.currency || DEFAULT_CURRENCY; + if (typeof floor === 'number' && !isNaN(floor)) { + imp.bidfloor = floor; + imp.bidfloorcur = floorCur; + } + + return imp; + }, + request(buildRequest, imps, bidderRequest, context) { + const req = buildRequest(imps, bidderRequest, context); + mergeDeep(req, { + at: 1, + ext: { + prebid: { + adapter: BIDDER_CODE, + version: '$prebid.version$' + } + } + }); + return req; + } +}); + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid(bid) { + const params = bid?.params; + if (!params) return false; + const { seat, region, partner } = normalizeBidParams(params); + if (typeof seat !== 'string' || !seat.length) return false; + if (!isAllowedPartnerRegion(partner, region)) return false; + return true; + }, + + buildRequests(validBidRequests = [], bidderRequest = {}) { + if (!validBidRequests.length) return []; + const filteredBidRequests = validBidRequests.filter((bidRequest) => spec.isBidRequestValid(bidRequest)); + if (!filteredBidRequests.length) return []; + + const bidRequestsByParams = filteredBidRequests.reduce((groups, bidRequest) => { + const { seat, region, partner } = normalizeBidParams(bidRequest.params); + const key = `${seat}|${region}|${partner}`; + groups[key] = groups[key] || []; + groups[key].push({ + ...bidRequest, + params: { + ...bidRequest.params, + seat, + region, + partner + } + }); + return groups; + }, {}); + + return Object.values(bidRequestsByParams).map((groupedBidRequests) => { + const { seat, region, partner } = groupedBidRequests[0].params; + const url = getEndpointUrl(seat, region, partner); + if (!url) return null; + return { + method: 'POST', + url, + data: CONVERTER.toORTB({ bidRequests: groupedBidRequests, bidderRequest }), + options: { + withCredentials: true, + contentType: 'text/plain' + } + }; + }).filter(Boolean); + }, + + interpretResponse(response, request) { + if (!response?.body || !request?.data) return []; + return CONVERTER.fromORTB({ request: request.data, response: response.body })?.bids || []; + }, + + getUserSyncs() { + return []; + }, + + onBidWon(bid) { + if (bid.burl) { + triggerPixel(bid.burl); + } + if (bid.nurl) { + triggerPixel(bid.nurl); + } + } +}; + +registerBidder(spec); diff --git a/modules/floxisBidAdapter.md b/modules/floxisBidAdapter.md new file mode 100644 index 00000000000..f36db0c6577 --- /dev/null +++ b/modules/floxisBidAdapter.md @@ -0,0 +1,59 @@ +# Overview + +``` +Module Name: Floxis Bidder Adapter +Module Type: Bidder Adapter +Maintainer: admin@floxis.tech +``` + +# Description + +The Floxis Bid Adapter enables integration with the Floxis programmatic advertising platform via Prebid.js. It supports banner, video (instream and outstream), and native formats. + +**Key Features:** +- Banner, Video and Native ad support +- OpenRTB 2.x compliant +- Privacy regulation compliance (GDPR, USP, GPP, COPPA) +- Prebid.js Floors Module support + +## Supported Media Types +- Banner +- Video +- Native + +## Floors Module Support +The Floxis Bid Adapter supports the Prebid.js [Floors Module](https://docs.prebid.org/dev-docs/modules/floors.html). Floor values are automatically included in the OpenRTB request as `imp.bidfloor` and `imp.bidfloorcur`. + +## Privacy +Privacy fields (GDPR, USP, GPP, COPPA) are handled by Prebid.js core and automatically included in the OpenRTB request. + +## Example Usage +```javascript +pbjs.addAdUnits([ + { + code: 'adunit-1', + mediaTypes: { banner: { sizes: [[300, 250]] } }, + bids: [{ + bidder: 'floxis', + params: { + seat: 'testSeat', + region: 'us-e', + partner: 'floxis' + } + }] + } +]); +``` + +# Configuration + +## Parameters + +| Name | Scope | Description | Example | Type | +| --- | --- | --- | --- | --- | +| `seat` | required | Seat identifier | `'testSeat'` | `string` | +| `region` | required | Region identifier for routing | `'us-e'` | `string` | +| `partner` | required | Partner identifier | `'floxis'` | `string` | + +## Testing +Unit tests are provided in `test/spec/modules/floxisBidAdapter_spec.js` and cover validation, request building, response interpretation, and bid-won notifications. diff --git a/modules/fpdModule/index.js b/modules/fpdModule/index.js index 4beb07b5656..6d18251d3d8 100644 --- a/modules/fpdModule/index.js +++ b/modules/fpdModule/index.js @@ -4,9 +4,9 @@ */ import { config } from '../../src/config.js'; import { module, getHook } from '../../src/hook.js'; -import {logError} from '../../src/utils.js'; -import {PbPromise} from '../../src/utils/promise.js'; -import {timedAuctionHook} from '../../src/utils/perfMetrics.js'; +import { logError } from '../../src/utils.js'; +import { PbPromise } from '../../src/utils/promise.js'; +import { timedAuctionHook } from '../../src/utils/perfMetrics.js'; const submodules = []; @@ -18,19 +18,19 @@ export function reset() { submodules.length = 0; } -export function processFpd({global = {}, bidder = {}} = {}) { +export function processFpd({ global = {}, bidder = {} } = {}) { const modConf = config.getConfig('firstPartyData') || {}; - let result = PbPromise.resolve({global, bidder}); + let result = PbPromise.resolve({ global, bidder }); submodules.sort((a, b) => { return ((a.queue || 1) - (b.queue || 1)); }).forEach(submodule => { result = result.then( - ({global, bidder}) => PbPromise.resolve(submodule.processFpd(modConf, {global, bidder})) + ({ global, bidder }) => PbPromise.resolve(submodule.processFpd(modConf, { global, bidder })) .catch((err) => { logError(`Error in FPD module ${submodule.name}`, err); return {}; }) - .then((result) => ({global: result.global || global, bidder: result.bidder || bidder})) + .then((result) => ({ global: result.global || global, bidder: result.bidder || bidder })) ); }); return result; diff --git a/modules/freepassBidAdapter.js b/modules/freepassBidAdapter.js index a765b5f5521..69373be46fc 100644 --- a/modules/freepassBidAdapter.js +++ b/modules/freepassBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {logMessage} from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { logMessage } from '../src/utils.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' const BIDDER_SERVICE_URL = 'https://bidding-dsp.ad-m.asia/dsp/api/bid/s/s/freepass'; @@ -108,7 +108,7 @@ export const spec = { interpretResponse(serverResponse, bidRequest) { logMessage('FreePass BidAdapter is interpreting server response: ', serverResponse); logMessage('FreePass BidAdapter is using bid request: ', bidRequest); - const bids = converter.fromORTB({response: serverResponse.body, request: bidRequest.data}).bids; + const bids = converter.fromORTB({ response: serverResponse.body, request: bidRequest.data }).bids; logMessage('FreePass BidAdapter interpreted ORTB bids as ', bids); return bids; diff --git a/modules/freepassIdSystem.js b/modules/freepassIdSystem.js index f00b2d6e629..1e5ccf46f20 100644 --- a/modules/freepassIdSystem.js +++ b/modules/freepassIdSystem.js @@ -50,7 +50,7 @@ export const freepassIdSubmodule = { idObject.freepassId = freepassData.commonId; } - return {id: idObject}; + return { id: idObject }; }, extendId: function (config, _, storedId) { diff --git a/modules/ftrackIdSystem.js b/modules/ftrackIdSystem.js index d22d7b28a35..f5612996c9c 100644 --- a/modules/ftrackIdSystem.js +++ b/modules/ftrackIdSystem.js @@ -6,10 +6,10 @@ */ import * as utils from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -24,7 +24,7 @@ const LOCAL_STORAGE_EXP_DAYS = 30; const LOCAL_STORAGE = 'html5'; const FTRACK_STORAGE_NAME = 'ftrackId'; const FTRACK_PRIVACY_STORAGE_NAME = `${FTRACK_STORAGE_NAME}_privacy`; -const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); const consentInfo = { gdpr: { @@ -191,7 +191,7 @@ export const ftrackIdSubmodule = { isThereConsent: function(consentData) { let consentValue = true; - const {gdpr, usp} = consentData ?? {}; + const { gdpr, usp } = consentData ?? {}; /* * Scenario 1: GDPR * if GDPR Applies is true|1, we do not have consent diff --git a/modules/fwsspBidAdapter.js b/modules/fwsspBidAdapter.js index f64c21e71c4..efd10a5c75c 100644 --- a/modules/fwsspBidAdapter.js +++ b/modules/fwsspBidAdapter.js @@ -13,7 +13,7 @@ export const spec = { code: BIDDER_CODE, gvlid: GVL_ID, supportedMediaTypes: [BANNER, VIDEO], - aliases: [ 'freewheel-mrm'], // aliases for fwssp + aliases: ['freewheel-mrm'], // aliases for fwssp /** * Determines whether or not the given bid request is valid. diff --git a/modules/gamAdServerVideo.js b/modules/gamAdServerVideo.js index 9613af93e4e..5f52c935554 100644 --- a/modules/gamAdServerVideo.js +++ b/modules/gamAdServerVideo.js @@ -22,13 +22,13 @@ import { parseSizesInput, parseUrl } from '../src/utils.js'; -import {DEFAULT_GAM_PARAMS, GAM_ENDPOINT, gdprParams} from '../libraries/gamUtils/gamUtils.js'; +import { DEFAULT_GAM_PARAMS, GAM_ENDPOINT, gdprParams } from '../libraries/gamUtils/gamUtils.js'; import { vastLocalCache } from '../src/videoCache.js'; import { fetch } from '../src/ajax.js'; import XMLUtil from '../libraries/xmlUtils/xmlUtils.js'; -import {getGlobalVarName} from '../src/buildOptions.js'; -import { uspDataHandler } from '../src/consentHandler.js'; +import { getGlobalVarName } from '../src/buildOptions.js'; +import { gppDataHandler, uspDataHandler } from '../src/consentHandler.js'; /** * @typedef {Object} DfpVideoParams * @@ -89,7 +89,7 @@ export function buildGamVideoUrl(options) { if (options.url) { // when both `url` and `params` are given, parsed url will be overwriten // with any matching param components - urlComponents = parseUrl(options.url, {noDecodeWholeURL: true}); + urlComponents = parseUrl(options.url, { noDecodeWholeURL: true }); if (isEmpty(options.params)) { return buildUrlFromAdserverUrlComponents(urlComponents, bid, options); @@ -119,6 +119,22 @@ export function buildGamVideoUrl(options) { gdprParams() ); + // The IMA player adds usp info, but not gpp info + // For cases where the CMP only exposes gpp but not usp, + // it is better to derive an usp string from the gpp info and include it in the url + if (window.google?.ima) { + const usPrivacy = uspDataHandler.getConsentData?.(); + const gpp = gppDataHandler.getConsentData?.(); + + if (!usPrivacy && gpp) { + // Extract an usPrivacy string from the GPP string if possible + const uspFromGpp = retrieveUspInfoFromGpp(gpp); + if (uspFromGpp) { + queryParams['us_privacy'] = uspFromGpp; + } + } + } + const descriptionUrl = getDescriptionUrl(bid, options, 'params'); if (descriptionUrl) { queryParams.description_url = descriptionUrl; } @@ -245,7 +261,7 @@ function getCustParams(bid, options, urlCustParams) { ); // TODO: WTF is this? just firing random events, guessing at the argument, hoping noone notices? - events.emit(EVENTS.SET_TARGETING, {[adUnit.code]: prebidTargetingSet}); + events.emit(EVENTS.SET_TARGETING, { [adUnit.code]: prebidTargetingSet }); // merge the prebid + publisher targeting sets const publisherTargetingSet = options?.params?.cust_params; @@ -311,7 +327,6 @@ export async function getVastXml(options, localCacheMap = vastLocalCache) { if (usPrivacy) { vastUrl.searchParams.set('us_privacy', usPrivacy); } - vastUrl = vastUrl.toString(); } @@ -329,6 +344,41 @@ export async function getVastXml(options, localCacheMap = vastLocalCache) { return gamVastWrapper; } +/** + * Extract a US Privacy string from the GPP data + */ +function retrieveUspInfoFromGpp(gpp) { + if (!gpp) { + return undefined; + } + const parsedSections = gpp.gppData?.parsedSections; + if (parsedSections) { + if (parsedSections.uspv1) { + const usp = parsedSections.uspv1; + return `${usp.Version}${usp.Notice}${usp.OptOutSale}${usp.LspaCovered}` + } else { + let saleOptOut; + let saleOptOutNotice; + Object.values(parsedSections).forEach(parsedSection => { + (Array.isArray(parsedSection) ? parsedSection : [parsedSection]).forEach(ps => { + const sectionSaleOptOut = ps.SaleOptOut; + const sectionSaleOptOutNotice = ps.SaleOptOutNotice; + if (saleOptOut === undefined && saleOptOutNotice === undefined && sectionSaleOptOut != null && sectionSaleOptOutNotice != null) { + saleOptOut = sectionSaleOptOut; + saleOptOutNotice = sectionSaleOptOutNotice; + } + }); + }); + if (saleOptOut !== undefined && saleOptOutNotice !== undefined) { + const uspOptOutSale = saleOptOut === 0 ? '-' : saleOptOut === 1 ? 'Y' : 'N'; + const uspOptOutNotice = saleOptOutNotice === 0 ? '-' : saleOptOutNotice === 1 ? 'Y' : 'N'; + const uspLspa = uspOptOutSale === '-' && uspOptOutNotice === '-' ? '-' : 'Y'; + return `1${uspOptOutNotice}${uspOptOutSale}${uspLspa}`; + } + } + } + return undefined +} export async function getBase64BlobContent(blobUrl) { const response = await fetch(blobUrl); diff --git a/modules/gamAdpod.js b/modules/gamAdpod.js index c21c71c0c3c..8aebb860c48 100644 --- a/modules/gamAdpod.js +++ b/modules/gamAdpod.js @@ -1,8 +1,8 @@ -import {submodule} from '../src/hook.js'; -import {buildUrl, deepAccess, formatQS, logError, parseSizesInput} from '../src/utils.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {DEFAULT_GAM_PARAMS, GAM_ENDPOINT, gdprParams} from '../libraries/gamUtils/gamUtils.js'; -import {registerVideoSupport} from '../src/adServerManager.js'; +import { submodule } from '../src/hook.js'; +import { buildUrl, deepAccess, formatQS, logError, parseSizesInput } from '../src/utils.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { DEFAULT_GAM_PARAMS, GAM_ENDPOINT, gdprParams } from '../libraries/gamUtils/gamUtils.js'; +import { registerVideoSupport } from '../src/adServerManager.js'; export const adpodUtils = {}; @@ -20,7 +20,7 @@ export const adpodUtils = {}; * @param {DfpAdpodOptions} options * @returns {string} A URL which calls DFP with custom adpod targeting key values to compete with rest of the demand in DFP */ -export function buildAdpodVideoUrl({code, params, callback} = {}) { +export function buildAdpodVideoUrl({ code, params, callback } = {}) { // TODO: the public API for this does not take in enough info to fill all DFP params (adUnit/bid), // and is marked "alpha": https://docs.prebid.org/dev-docs/publisher-api-reference/adServers.gam.buildAdpodVideoUrl.html if (!params || !callback) { diff --git a/modules/gamoshiBidAdapter.js b/modules/gamoshiBidAdapter.js index 66e74badf5e..a8611176e10 100644 --- a/modules/gamoshiBidAdapter.js +++ b/modules/gamoshiBidAdapter.js @@ -10,12 +10,12 @@ import { logWarn, mergeDeep } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {ortb25Translator} from '../libraries/ortb2.5Translator/translator.js'; -import {getCurrencyFromBidderRequest} from '../libraries/ortb2Utils/currency.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { ortb25Translator } from '../libraries/ortb2.5Translator/translator.js'; +import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const ENDPOINTS = { 'gamoshi': 'https://rtb.gamoshi.io', 'cleanmedianet': 'https://bidder.cleanmediaads.com' @@ -208,7 +208,7 @@ export const spec = { bidResponse.ext['utrk'] .forEach(pixel => { const url = helper.replaceMacros(pixel.url, params); - syncs.push({type: pixel.type, url}); + syncs.push({ type: pixel.type, url }); }); } if (Array.isArray(bidResponse.seatbid)) { @@ -219,7 +219,7 @@ export const spec = { bid.ext['utrk'] .forEach(pixel => { const url = helper.replaceMacros(pixel.url, params); - syncs.push({type: pixel.type, url}); + syncs.push({ type: pixel.type, url }); }); } }); diff --git a/modules/gemiusIdSystem.ts b/modules/gemiusIdSystem.ts index 08b4cf1b053..2894eeaab9b 100644 --- a/modules/gemiusIdSystem.ts +++ b/modules/gemiusIdSystem.ts @@ -60,10 +60,10 @@ function retrieveId(primaryScriptWindow: PrimaryScriptWindow, callback: (id: Ser try { primaryScriptWindow.gemius_cmd('get_ruid', function (ruid, desc) { if (desc.status === 'ok') { - setResult({id: ruid}); + setResult({ id: ruid }); } else if (desc.status === 'no-consent') { logInfo(LOG_PREFIX + 'failed to get id, no consent'); - setResult({id: null}); + setResult({ id: null }); } else { logError(LOG_PREFIX + 'failed to get id, response: ' + desc.status); setResult(); @@ -80,15 +80,15 @@ export const gemiusIdSubmodule: IdProviderSpec = { gvlid: GVLID, decode(value) { if (isStr(value?.['id'])) { - return {[MODULE_NAME]: value['id']}; + return { [MODULE_NAME]: value['id'] }; } return undefined; }, - getId(_, {gdpr: consentData}: Partial = {}) { + getId(_, { gdpr: consentData }: Partial = {}) { if (consentData && typeof consentData.gdprApplies === 'boolean' && consentData.gdprApplies) { if (REQUIRED_PURPOSES.some(purposeId => !(consentData.vendorData?.purpose as any)?.consents?.[purposeId])) { logInfo(LOG_PREFIX + 'getId, no consent'); - return {id: {id: null}}; + return { id: { id: null } }; } } diff --git a/modules/genericAnalyticsAdapter.ts b/modules/genericAnalyticsAdapter.ts index eca61dce170..0b22b529ef0 100644 --- a/modules/genericAnalyticsAdapter.ts +++ b/modules/genericAnalyticsAdapter.ts @@ -1,11 +1,11 @@ -import AnalyticsAdapter, {type DefaultOptions} from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {prefixLog, isPlainObject} from '../src/utils.js'; -import {type Events, has as hasEvent} from '../src/events.js'; +import AnalyticsAdapter, { type DefaultOptions } from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; +import { prefixLog, isPlainObject } from '../src/utils.js'; +import { type Events, has as hasEvent } from '../src/events.js'; import adapterManager from '../src/adapterManager.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import type {AnyFunction} from "../src/types/functions"; +import { ajaxBuilder } from '../src/ajax.js'; +import type { AnyFunction } from "../src/types/functions"; -type EventMapping = {[E in keyof Events]?: (payload: Events[E][0]) => any}; +type EventMapping = { [E in keyof Events]?: (payload: Events[E][0]) => any }; type BaseOptions = { /** @@ -92,8 +92,8 @@ const TYPES = { const MAX_CALL_DEPTH = 20; export function GenericAnalytics() { - const parent = AnalyticsAdapter<'generic'>({analyticsType: 'endpoint'}); - const {logError, logWarn} = prefixLog('Generic analytics:'); + const parent = AnalyticsAdapter<'generic'>({ analyticsType: 'endpoint' }); + const { logError, logWarn } = prefixLog('Generic analytics:'); let batch = []; let callDepth = 0; let options, handler, timer, translate; @@ -161,7 +161,7 @@ export function GenericAnalytics() { if (!eventHandlers) { return (data) => data; } - return function ({eventType, args}) { + return function ({ eventType, args }) { if (eventHandlers.hasOwnProperty(eventType)) { try { return eventHandlers[eventType](args); @@ -205,16 +205,16 @@ export function GenericAnalytics() { ) } -export function defaultHandler({url, method, batchSize, ajax = ajaxBuilder()}) { +export function defaultHandler({ url, method, batchSize, ajax = ajaxBuilder() }) { const callbacks = { success() {}, error() {} } const extract = batchSize > 1 ? (events) => events : (events) => events[0]; - const serialize = method === 'GET' ? (data) => ({data: JSON.stringify(data)}) : (data) => JSON.stringify(data); + const serialize = method === 'GET' ? (data) => ({ data: JSON.stringify(data) }) : (data) => JSON.stringify(data); return function (events) { - ajax(url, callbacks, serialize(extract(events)), {method, keepalive: true}) + ajax(url, callbacks, serialize(extract(events)), { method, keepalive: true }) } } diff --git a/modules/geolocationRtdProvider.ts b/modules/geolocationRtdProvider.ts index 5283a33a1a1..9a8357a289b 100644 --- a/modules/geolocationRtdProvider.ts +++ b/modules/geolocationRtdProvider.ts @@ -1,11 +1,11 @@ -import {submodule} from '../src/hook.js'; -import {isFn, logError, deepAccess, deepSetValue, logInfo, logWarn, timestamp} from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { isFn, logError, deepAccess, deepSetValue, logInfo, logWarn, timestamp } from '../src/utils.js'; import { ACTIVITY_TRANSMIT_PRECISE_GEO } from '../src/activities/activities.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; import { isActivityAllowed } from '../src/activities/rules.js'; import { activityParams } from '../src/activities/activityParams.js'; -import {VENDORLESS_GVLID} from '../src/consentHandler.js'; -import type {RtdProviderSpec} from "./rtdModule/spec.ts"; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; +import type { RtdProviderSpec } from "./rtdModule/spec.ts"; let permissionsAvailable = true; let geolocation; diff --git a/modules/getintentBidAdapter.js b/modules/getintentBidAdapter.js index e85fd4b6f28..5d6499b418c 100644 --- a/modules/getintentBidAdapter.js +++ b/modules/getintentBidAdapter.js @@ -1,4 +1,4 @@ -import {getBidIdParameter, isFn, isInteger, logError} from '../src/utils.js'; +import { getBidIdParameter, isFn, isInteger, logError } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; /** diff --git a/modules/gjirafaBidAdapter.js b/modules/gjirafaBidAdapter.js index 3218b32732a..2c1a4f87131 100644 --- a/modules/gjirafaBidAdapter.js +++ b/modules/gjirafaBidAdapter.js @@ -17,7 +17,7 @@ const SIZE_SEPARATOR = ';'; const BISKO_ID = 'biskoId'; const STORAGE_ID = 'bisko-sid'; const SEGMENTS = 'biskoSegments'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/glomexBidAdapter.js b/modules/glomexBidAdapter.js index 8a1ae7292f8..88bb43fadc6 100644 --- a/modules/glomexBidAdapter.js +++ b/modules/glomexBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const ENDPOINT = 'https://prebid.mes.glomex.cloud/request-bid' const BIDDER_CODE = 'glomex' @@ -32,7 +32,8 @@ export const spec = { isAmp: refererInfo.isAmp, numIframes: refererInfo.numIframes, reachedTop: refererInfo.reachedTop, - referer: refererInfo.topmostLocation}, + referer: refererInfo.topmostLocation + }, gdprConsent: { consentString: gdprConsent.consentString, gdprApplies: gdprConsent.gdprApplies diff --git a/modules/gmosspBidAdapter.js b/modules/gmosspBidAdapter.js index 7bff19bb2c0..c043e852831 100644 --- a/modules/gmosspBidAdapter.js +++ b/modules/gmosspBidAdapter.js @@ -1,6 +1,6 @@ import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; import { diff --git a/modules/gnetBidAdapter.js b/modules/gnetBidAdapter.js index 1bcc774e351..da99983ea0c 100644 --- a/modules/gnetBidAdapter.js +++ b/modules/gnetBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { _each, isEmpty, parseSizesInput } from '../src/utils.js'; import { BANNER } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -13,7 +13,7 @@ import {ajax} from '../src/ajax.js'; const BIDDER_CODE = 'gnet'; const ENDPOINT = 'https://service.gnetrtb.com/api'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/goldbachBidAdapter.js b/modules/goldbachBidAdapter.js index 3912df96615..84cca2ebbb3 100644 --- a/modules/goldbachBidAdapter.js +++ b/modules/goldbachBidAdapter.js @@ -184,7 +184,7 @@ const converter = ortbConverter({ /* Logging */ const sendLog = (data, percentage = 0.0001) => { if (Math.random() > percentage) return; - const encodedData = `data=${window.btoa(JSON.stringify({...data, source: 'goldbach_pbjs', projectedAmount: (1 / percentage)}))}`; + const encodedData = `data=${window.btoa(JSON.stringify({ ...data, source: 'goldbach_pbjs', projectedAmount: (1 / percentage) }))}`; ajax(URL_LOGGING, null, encodedData, { withCredentials: false, method: METHOD, @@ -214,7 +214,7 @@ export const spec = { }; }, interpretResponse: function (ortbResponse, request) { - const bids = converter.fromORTB({response: ortbResponse.body, request: request.data}).bids; + const bids = converter.fromORTB({ response: ortbResponse.body, request: request.data }).bids; return bids }, getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { diff --git a/modules/gppControl_usnat.js b/modules/gppControl_usnat.js index b38fc1a9d29..4aec1c11d9a 100644 --- a/modules/gppControl_usnat.js +++ b/modules/gppControl_usnat.js @@ -1,5 +1,5 @@ -import {config} from '../src/config.js'; -import {setupRules} from '../libraries/mspa/activityControls.js'; +import { config } from '../src/config.js'; +import { setupRules } from '../libraries/mspa/activityControls.js'; let setupDone = false; diff --git a/modules/gppControl_usstates.ts b/modules/gppControl_usstates.ts index 826fd74369d..3297d0158b2 100644 --- a/modules/gppControl_usstates.ts +++ b/modules/gppControl_usstates.ts @@ -1,6 +1,6 @@ -import {config} from '../src/config.js'; -import {setupRules} from '../libraries/mspa/activityControls.js'; -import {deepSetValue, prefixLog} from '../src/utils.js'; +import { config } from '../src/config.js'; +import { setupRules } from '../libraries/mspa/activityControls.js'; +import { deepSetValue, prefixLog } from '../src/utils.js'; const FIELDS = { Version: 0, @@ -29,7 +29,7 @@ const FIELDS = { * List fields are also copied, but forced to the "correct" length (by truncating or padding with nulls); * additionally, elements within them can be moved around using the `move` argument. */ -export function normalizer({nullify = [], move = {}, fn}: { +export function normalizer({ nullify = [], move = {}, fn }: { /** * list of fields to force to null */ @@ -108,8 +108,8 @@ export const NORMALIZATIONS = { } } }), - 9: normalizer({fn: scalarMinorsAreChildren}), - 10: normalizer({fn: scalarMinorsAreChildren}), + 9: normalizer({ fn: scalarMinorsAreChildren }), + 10: normalizer({ fn: scalarMinorsAreChildren }), 11: normalizer({ move: { SensitiveDataProcessing: { @@ -146,7 +146,7 @@ export const DEFAULT_SID_MAPPING = { export const getSections = (() => { const allSIDs = Object.keys(DEFAULT_SID_MAPPING).map(Number); - return function ({sections = {}, sids = allSIDs} = {}) { + return function ({ sections = {}, sids = allSIDs } = {}) { return sids.map(sid => { const logger = prefixLog(`Cannot set up MSPA controls for SID ${sid}:`); const ov = sections[sid] || {}; diff --git a/modules/gptPreAuction.ts b/modules/gptPreAuction.ts index db2978e1302..3c9b071098e 100644 --- a/modules/gptPreAuction.ts +++ b/modules/gptPreAuction.ts @@ -13,9 +13,9 @@ import { pick, uniques } from '../src/utils.js'; -import type {SlotMatchingFn} from '../src/targeting.ts'; -import type {AdUnitCode} from '../src/types/common.d.ts'; -import type {AdUnit} from '../src/adUnits.ts'; +import type { SlotMatchingFn } from '../src/targeting.ts'; +import type { AdUnitCode } from '../src/types/common.d.ts'; +import type { AdUnit } from '../src/adUnits.ts'; const MODULE_NAME = 'GPT Pre-Auction'; export let _currentConfig: any = {}; @@ -164,7 +164,7 @@ const setPpsConfigFromTargetingSet = (next, targetingSet) => { // set gpt config const auctionsIds = getAuctionsIdsFromTargeting(targetingSet); const signals = getSignalsIntersection(getSignalsArrayByAuctionsIds(auctionsIds)); - window.googletag.setConfig && window.googletag.setConfig({pps: { taxonomies: signals }}); + window.googletag.setConfig && window.googletag.setConfig({ pps: { taxonomies: signals } }); next(targetingSet); }; @@ -221,8 +221,8 @@ const handleSetGptConfig = moduleConfig => { } else { logInfo(`${MODULE_NAME}: Turning off module`); _currentConfig = {}; - getHook('makeBidRequests').getHooks({hook: makeBidRequestsHook}).remove(); - getHook('targetingDone').getHooks({hook: setPpsConfigFromTargetingSet}).remove(); + getHook('makeBidRequests').getHooks({ hook: makeBidRequestsHook }).remove(); + getHook('targetingDone').getHooks({ hook: setPpsConfigFromTargetingSet }).remove(); hooksAdded = false; } }; diff --git a/modules/gravitoIdSystem.js b/modules/gravitoIdSystem.js index cc02c6a103e..8f2e7e4b4df 100644 --- a/modules/gravitoIdSystem.js +++ b/modules/gravitoIdSystem.js @@ -6,11 +6,11 @@ */ import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; const MODULE_NAME = 'gravitompId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); export const cookieKey = 'gravitompId'; @@ -34,7 +34,7 @@ export const gravitoIdSystemSubmodule = { const result = { gravitompId: newId } - return {id: result}; + return { id: result }; }, /** @@ -49,7 +49,7 @@ export const gravitoIdSystemSubmodule = { if (value.gravitompId) { result = value.gravitompId } - return {gravitompId: result}; + return { gravitompId: result }; } return undefined; }, diff --git a/modules/greenbidsAnalyticsAdapter.js b/modules/greenbidsAnalyticsAdapter.js index 99ce89ee4d1..151b97553ed 100644 --- a/modules/greenbidsAnalyticsAdapter.js +++ b/modules/greenbidsAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {deepClone, generateUUID, logError, logInfo, logWarn, getParameterByName} from '../src/utils.js'; +import { deepClone, generateUUID, logError, logInfo, logWarn, getParameterByName } from '../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid @@ -52,7 +52,7 @@ export const isSampled = function(greenbidsId, samplingRate, exploratorySampling return isExtraSampled; } -export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER, analyticsType}), { +export const greenbidsAnalyticsAdapter = Object.assign(adapter({ ANALYTICS_SERVER, analyticsType }), { cachedAuctions: {}, exploratorySamplingSplit: 0.9, @@ -171,7 +171,7 @@ export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER } }, createBidMessage(auctionEndArgs) { - const {auctionId, timestamp, auctionEnd, adUnits, bidsReceived, noBids} = auctionEndArgs; + const { auctionId, timestamp, auctionEnd, adUnits, bidsReceived, noBids } = auctionEndArgs; const cachedAuction = this.getCachedAuction(auctionId); const message = this.createCommonMessage(auctionId); const timeoutBids = cachedAuction.timeoutBids || []; @@ -183,9 +183,9 @@ export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER message.adUnits.push({ code: adUnitCode, mediaTypes: { - ...(adUnit.mediaTypes?.banner !== undefined) && {banner: adUnit.mediaTypes.banner}, - ...(adUnit.mediaTypes?.video !== undefined) && {video: adUnit.mediaTypes.video}, - ...(adUnit.mediaTypes?.native !== undefined) && {native: adUnit.mediaTypes.native} + ...(adUnit.mediaTypes?.banner !== undefined) && { banner: adUnit.mediaTypes.banner }, + ...(adUnit.mediaTypes?.video !== undefined) && { video: adUnit.mediaTypes.video }, + ...(adUnit.mediaTypes?.native !== undefined) && { native: adUnit.mediaTypes.native } }, ortb2Imp: adUnit.ortb2Imp || {}, bidders: [], @@ -243,7 +243,7 @@ export const greenbidsAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER cachedAuction.billingId = billableArgs.billingId || 'unknown_billing_id'; } }, - track({eventType, args}) { + track({ eventType, args }) { try { if (eventType === AUCTION_INIT) { this.handleAuctionInit(args); diff --git a/modules/gridBidAdapter.js b/modules/gridBidAdapter.js index e894154e6d1..31a592cf6b6 100644 --- a/modules/gridBidAdapter.js +++ b/modules/gridBidAdapter.js @@ -60,7 +60,7 @@ export const spec = { code: BIDDER_CODE, gvlid: GVLID, aliases: ['playwire', 'adlivetech', 'gridNM'], - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], /** * Determines whether or not the given bid request is valid. * @@ -89,7 +89,7 @@ export const spec = { let userExt = null; let endpoint = null; let forceBidderName = false; - let {bidderRequestId, gdprConsent, uspConsent, timeout, refererInfo, gppConsent} = bidderRequest || {}; + let { bidderRequestId, gdprConsent, uspConsent, timeout, refererInfo, gppConsent } = bidderRequest || {}; const referer = refererInfo ? encodeURIComponent(refererInfo.page) : ''; const tmax = parseInt(timeout) || null; @@ -262,7 +262,7 @@ export const spec = { } if (gdprConsent && gdprConsent.consentString) { - userExt = {consent: gdprConsent.consentString}; + userExt = { consent: gdprConsent.consentString }; } const ortb2UserExtDevice = deepAccess(bidderRequest, 'ortb2.user.ext.device'); @@ -348,7 +348,7 @@ export const spec = { if (uspConsent) { if (!request.regs) { - request.regs = {ext: {}}; + request.regs = { ext: {} }; } if (!request.regs.ext) { request.regs.ext = {}; @@ -365,7 +365,7 @@ export const spec = { if (ortb2Regs?.ext?.dsa) { if (!request.regs) { - request.regs = {ext: {}}; + request.regs = { ext: {} }; } if (!request.regs.ext) { request.regs.ext = {}; @@ -383,7 +383,7 @@ export const spec = { } const genre = deepAccess(site, 'content.genre'); if (genre && typeof genre === 'string') { - request.site.content = {...request.site.content, genre}; + request.site.content = { ...request.site.content, genre }; } const data = deepAccess(site, 'content.data'); if (data && data.length) { @@ -392,7 +392,7 @@ export const spec = { } const id = deepAccess(site, 'content.id'); if (id) { - request.site.content = {...request.site.content, id}; + request.site.content = { ...request.site.content, id }; } } }); @@ -483,7 +483,7 @@ export const spec = { }, onDataDeletionRequest: function(data) { - spec.ajaxCall(USP_DELETE_DATA_HANDLER, null, null, {method: 'GET'}); + spec.ajaxCall(USP_DELETE_DATA_HANDLER, null, null, { method: 'GET' }); } }; @@ -501,7 +501,7 @@ function _getFloor (mediaTypes, bid) { const floorInfo = bid.getFloor({ currency: 'USD', mediaType: curMediaType, - size: bid.sizes.map(([w, h]) => ({w, h})) + size: bid.sizes.map(([w, h]) => ({ w, h })) }); if (isPlainObject(floorInfo) && diff --git a/modules/growadsBidAdapter.js b/modules/growadsBidAdapter.js index 4b5b97f965a..42f02625db8 100644 --- a/modules/growadsBidAdapter.js +++ b/modules/growadsBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import {deepAccess, _each, triggerPixel, getBidIdParameter} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { deepAccess, _each, triggerPixel, getBidIdParameter } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'growads'; diff --git a/modules/growthCodeAnalyticsAdapter.js b/modules/growthCodeAnalyticsAdapter.js index 5c936767cdf..93d9a2b10dd 100644 --- a/modules/growthCodeAnalyticsAdapter.js +++ b/modules/growthCodeAnalyticsAdapter.js @@ -6,16 +6,16 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import * as utils from '../src/utils.js'; import { EVENTS } from '../src/constants.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {logError, logInfo} from '../src/utils.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { logError, logInfo } from '../src/utils.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_NAME = 'growthCodeAnalytics'; const DEFAULT_PID = 'INVALID_PID' const ENDPOINT_URL = 'https://analytics.gcprivacy.com/v3/pb/analytics' -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME }); const sessionId = utils.generateUUID(); @@ -29,8 +29,8 @@ let startAuction = 0; let bidRequestTimeout = 0; const analyticsType = 'endpoint'; -const growthCodeAnalyticsAdapter = Object.assign(adapter({url: url, analyticsType}), { - track({eventType, args}) { +const growthCodeAnalyticsAdapter = Object.assign(adapter({ url: url, analyticsType }), { + track({ eventType, args }) { const eventData = args ? utils.deepClone(args) : {}; let data = {}; if (!trackEvents.includes(eventType)) return; @@ -159,7 +159,7 @@ function logToServer() { error: error => { logInfo(MODULE_NAME + ' Problem Send Data to Server: ' + error) } - }, JSON.stringify(data), {method: 'POST', withCredentials: true}) + }, JSON.stringify(data), { method: 'POST', withCredentials: true }) eventQueue = [ ]; diff --git a/modules/growthCodeIdSystem.js b/modules/growthCodeIdSystem.js index 2da339e1b4a..4c6d48f4932 100644 --- a/modules/growthCodeIdSystem.js +++ b/modules/growthCodeIdSystem.js @@ -6,8 +6,8 @@ */ import { submodule } from '../src/hook.js' -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -67,7 +67,7 @@ export const growthCodeIdSubmodule = { ids = ids.concat(data) } - return {id: ids} + return { id: ids } }, }; diff --git a/modules/growthCodeRtdProvider.js b/modules/growthCodeRtdProvider.js index 807b17f351d..3e5a5b9119e 100644 --- a/modules/growthCodeRtdProvider.js +++ b/modules/growthCodeRtdProvider.js @@ -9,7 +9,7 @@ import { } from '../src/utils.js'; import * as ajax from '../src/ajax.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const MODULE_NAME = 'growthCodeRtd'; const LOG_PREFIX = 'GrowthCodeRtd: '; @@ -99,7 +99,7 @@ function callServer(configParams, items, expiresAt, userConsent) { error: error => { logError(LOG_PREFIX + 'ID fetch encountered an error', error); } - }, undefined, {method: 'GET', withCredentials: true}) + }, undefined, { method: 'GET', withCredentials: true }) } return true; diff --git a/modules/gumgumBidAdapter.js b/modules/gumgumBidAdapter.js index 3f7339a4f08..1858997f755 100644 --- a/modules/gumgumBidAdapter.js +++ b/modules/gumgumBidAdapter.js @@ -1,12 +1,11 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {_each, deepAccess, getWinDimensions, logError, logWarn, parseSizesInput} from '../src/utils.js'; -import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { _each, deepAccess, getWinDimensions, logError, logWarn, parseSizesInput } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getStorageManager} from '../src/storageManager.js'; - -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; +import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -18,7 +17,7 @@ import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.j */ const BIDDER_CODE = 'gumgum'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const ALIAS_BIDDER_CODE = ['gg']; const BID_ENDPOINT = `https://g2.gumgum.com/hbid/imp`; const JCSI = { t: 0, rq: 8, pbv: '$prebid.version$' } @@ -302,6 +301,78 @@ function _getDeviceData(ortb2Data) { }, {}); } +/** + * Retrieves content metadata from the ORTB2 object + * Supports both site.content and app.content (site takes priority) + * @param {Object} ortb2Data ORTB2 object + * @returns {Object} Content parameters + */ +function _getContentParams(ortb2Data) { + // Check site.content first, then app.content + const siteContent = deepAccess(ortb2Data, 'site.content'); + const appContent = deepAccess(ortb2Data, 'app.content'); + const content = siteContent || appContent; + + if (!content) { + return {}; + } + + const contentParams = {}; + contentParams.itype = siteContent ? 'site' : 'app'; + + // Basic content fields + if (content.id) contentParams.cid = content.id; + if (content.episode !== undefined && content.episode !== null) contentParams.cepisode = content.episode; + if (content.title) contentParams.ctitle = content.title; + if (content.series) contentParams.cseries = content.series; + if (content.season) contentParams.cseason = content.season; + if (content.genre) contentParams.cgenre = content.genre; + if (content.contentrating) contentParams.crating = content.contentrating; + if (content.userrating) contentParams.cur = content.userrating; + if (content.context !== undefined && content.context !== null) contentParams.cctx = content.context; + if (content.livestream !== undefined && content.livestream !== null) contentParams.clive = content.livestream; + if (content.len !== undefined && content.len !== null) contentParams.clen = content.len; + if (content.language) contentParams.clang = content.language; + if (content.url) contentParams.curl = content.url; + if (content.cattax !== undefined && content.cattax !== null) contentParams.cattax = content.cattax; + if (content.prodq !== undefined && content.prodq !== null) contentParams.cprodq = content.prodq; + if (content.qagmediarating !== undefined && content.qagmediarating !== null) contentParams.cqag = content.qagmediarating; + + // Handle keywords - can be string or array + if (content.keywords) { + if (Array.isArray(content.keywords)) { + contentParams.ckw = content.keywords.join(','); + } else if (typeof content.keywords === 'string') { + contentParams.ckw = content.keywords; + } + } + + // Handle cat array + if (content.cat && Array.isArray(content.cat) && content.cat.length > 0) { + contentParams.ccat = content.cat.join(','); + } + + // Handle producer fields + if (content.producer) { + if (content.producer.id) contentParams.cpid = content.producer.id; + if (content.producer.name) contentParams.cpname = content.producer.name; + } + + // Channel fields + if (content.channel) { + if (content.channel.id) contentParams.cchannelid = content.channel.id; + if (content.channel.name) contentParams.cchannel = content.channel.name; + if (content.channel.domain) contentParams.cchanneldomain = content.channel.domain; + } + + // Network fields + if (content.network) { + if (content.network.name) contentParams.cnetwork = content.network.name; + } + + return contentParams; +} + /** * loops through bannerSizes array to get greatest slot dimensions * @param {number[][]} sizes @@ -324,28 +395,53 @@ function getGreatestDimensions(sizes) { return [maxw, maxh]; } -function getEids(userId) { - const idProperties = [ - 'uid', - 'eid', - 'lipbid', - 'envelope', - 'id' - ]; - - return Object.keys(userId).reduce(function (eids, provider) { - const eid = userId[provider]; - switch (typeof eid) { - case 'string': - eids[provider] = eid; - break; - - case 'object': - const idProp = idProperties.filter(prop => eid.hasOwnProperty(prop)); - idProp.length && (eids[provider] = eid[idProp[0]]); - break; +function getFirstUid(eid) { + if (!eid || !Array.isArray(eid.uids)) return null; + return eid.uids.find(uid => uid && uid.id); +} + +function getUserEids(bidRequest, bidderRequest) { + const bidderRequestEids = deepAccess(bidderRequest, 'ortb2.user.ext.eids'); + if (Array.isArray(bidderRequestEids) && bidderRequestEids.length) { + return bidderRequestEids; + } + const bidEids = deepAccess(bidRequest, 'userIdAsEids'); + if (Array.isArray(bidEids) && bidEids.length) { + return bidEids; + } + const bidUserEids = deepAccess(bidRequest, 'user.ext.eids'); + if (Array.isArray(bidUserEids) && bidUserEids.length) { + return bidUserEids; + } + return []; +} + +function isPubProvidedIdEid(eid) { + const source = (eid && eid.source) ? eid.source.toLowerCase() : ''; + if (!source || !pubProvidedIdSources.includes(source) || !Array.isArray(eid.uids)) return false; + return eid.uids.some(uid => uid && uid.ext && uid.ext.stype); +} + +function getEidsFromEidsArray(eids) { + return (Array.isArray(eids) ? eids : []).reduce((ids, eid) => { + const source = (eid.source || '').toLowerCase(); + if (source === 'uidapi.com') { + const uid = getFirstUid(eid); + if (uid) { + ids.uid2 = uid.id; + } + } else if (source === 'liveramp.com') { + const uid = getFirstUid(eid); + if (uid) { + ids.idl_env = uid.id; + } + } else if (source === 'adserver.org' && Array.isArray(eid.uids)) { + const tdidUid = eid.uids.find(uid => uid && uid.id && uid.ext && uid.ext.rtiPartner === 'TDID'); + if (tdidUid) { + ids.tdid = tdidUid.id; + } } - return eids; + return ids; }, {}); } @@ -369,12 +465,12 @@ function buildRequests(validBidRequests, bidderRequest) { bidId, mediaTypes = {}, params = {}, - userId = {}, ortb2Imp, adUnitCode = '' } = bidRequest; const { currency, floor } = _getFloor(mediaTypes, params.bidfloor, bidRequest); - const eids = getEids(userId); + const userEids = getUserEids(bidRequest, bidderRequest); + const eids = getEidsFromEidsArray(userEids); const gpid = deepAccess(ortb2Imp, 'ext.gpid'); const paapiEligible = deepAccess(ortb2Imp, 'ext.ae') === 1 let sizes = [1, 1]; @@ -399,16 +495,20 @@ function buildRequests(validBidRequests, bidderRequest) { } } // Send filtered pubProvidedId's - if (userId && userId.pubProvidedId) { - const filteredData = userId.pubProvidedId.filter(item => pubProvidedIdSources.includes(item.source)); + if (userEids.length) { + const filteredData = userEids.filter(isPubProvidedIdEid); const maxLength = 1800; // replace this with your desired maximum length const truncatedJsonString = jsoStringifynWithMaxLength(filteredData, maxLength); - data.pubProvidedId = truncatedJsonString + if (filteredData.length) { + data.pubProvidedId = truncatedJsonString + } } // ADJS-1286 Read id5 id linktype field - if (userId && userId.id5id && userId.id5id.uid && userId.id5id.ext) { - data.id5Id = userId.id5id.uid || null - data.id5IdLinkType = userId.id5id.ext.linkType || null + const id5Eid = userEids.find(eid => (eid.source || '').toLowerCase() === 'id5-sync.com'); + const id5Uid = getFirstUid(id5Eid); + if (id5Uid && id5Uid.ext) { + data.id5Id = id5Uid.id || null + data.id5IdLinkType = id5Uid.ext.linkType || null } // ADTS-169 add adUnitCode to requests if (adUnitCode) data.aun = adUnitCode; @@ -436,9 +536,10 @@ function buildRequests(validBidRequests, bidderRequest) { } if (bidderRequest && bidderRequest.ortb2 && bidderRequest.ortb2.site) { setIrisId(data, bidderRequest.ortb2.site, params); - const curl = bidderRequest.ortb2.site.content?.url; - if (curl) data.curl = curl; } + // Extract content metadata from ortb2 + const contentParams = _getContentParams(bidderRequest?.ortb2); + Object.assign(data, contentParams); if (params.iriscat && typeof params.iriscat === 'string') { data.iriscat = params.iriscat; } @@ -651,7 +752,7 @@ function interpretResponse(serverResponse, bidRequest) { // added logic for in-slot multi-szie } else if ((product === 2 && sizes.includes('1x1')) || product === 3) { const requestSizesThatMatchResponse = (bidRequest.sizes && bidRequest.sizes.reduce((result, current) => { - const [ width, height ] = current; + const [width, height] = current; if (responseWidth === width && responseHeight === height) result.push(current.join('x')); return result }, [])) || []; diff --git a/modules/h12mediaBidAdapter.js b/modules/h12mediaBidAdapter.js index 963ae660e57..63e00622176 100644 --- a/modules/h12mediaBidAdapter.js +++ b/modules/h12mediaBidAdapter.js @@ -66,7 +66,7 @@ export const spec = { return { method: 'POST', url: requestUrl, - options: {withCredentials: true}, + options: { withCredentials: true }, data: { gdpr: !!deepAccess(bidderRequest, 'gdprConsent.gdprApplies', false), gdpr_cs: deepAccess(bidderRequest, 'gdprConsent.consentString', ''), @@ -219,7 +219,7 @@ function getClientDimensions() { function getDocumentDimensions() { try { - const {document: {documentElement, body}} = getWinDimensions(); + const { document: { documentElement, body } } = getWinDimensions(); const width = body.clientWidth; const height = Math.max(body.scrollHeight, body.offsetHeight, documentElement.clientHeight, documentElement.scrollHeight, documentElement.offsetHeight); return [width, height]; diff --git a/modules/hadronAnalyticsAdapter.js b/modules/hadronAnalyticsAdapter.js index c01e33bc6a2..37c1478fcb8 100644 --- a/modules/hadronAnalyticsAdapter.js +++ b/modules/hadronAnalyticsAdapter.js @@ -3,9 +3,9 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import * as utils from '../src/utils.js'; import { EVENTS } from '../src/constants.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; /** @@ -18,7 +18,7 @@ const DEFAULT_PARTNER_ID = 0; const AU_GVLID = 561; const MODULE_CODE = 'hadronAnalytics'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); var viewId = utils.generateUUID(); @@ -47,8 +47,8 @@ var startAuction = 0; var bidRequestTimeout = 0; const analyticsType = 'endpoint'; -const hadronAnalyticsAdapter = Object.assign(adapter({url: HADRON_ANALYTICS_URL, analyticsType}), { - track({eventType, args}) { +const hadronAnalyticsAdapter = Object.assign(adapter({ url: HADRON_ANALYTICS_URL, analyticsType }), { + track({ eventType, args }) { args = args ? utils.deepClone(args) : {}; var data = {}; if (!eventsToTrack.includes(eventType)) return; diff --git a/modules/hadronIdSystem.js b/modules/hadronIdSystem.js index ccd63bc0184..a87b75b6838 100644 --- a/modules/hadronIdSystem.js +++ b/modules/hadronIdSystem.js @@ -5,12 +5,12 @@ * @requires module:modules/userId */ -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isFn, isStr, isPlainObject, logError, logInfo} from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { isFn, isStr, isPlainObject, logError, logInfo } from '../src/utils.js'; import { config } from '../src/config.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../src/adapterManager.js'; /** @@ -25,7 +25,7 @@ export const LS_TAM_KEY = 'auHadronId'; const AU_GVLID = 561; const DEFAULT_HADRON_URL_ENDPOINT = 'https://id.hadron.ad.gt/api/v1/pbhid'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** * Param or default. @@ -89,7 +89,7 @@ export const hadronIdSubmodule = { if (isStr(hadronId) && hadronId.length > 0) { logInfo(LOG_PREFIX, `${LS_TAM_KEY} found in localStorage = ${hadronId}`) // return {callback: function(cb) { cb(hadronId) }}; - return {id: hadronId} + return { id: hadronId } } const partnerId = config.params.partnerId | 0; const resp = function (callback) { @@ -144,9 +144,9 @@ export const hadronIdSubmodule = { logInfo(LOG_PREFIX, `${MODULE_NAME} not found, calling home (${url})`); - ajax(url, callbacks, undefined, {method: 'GET'}); + ajax(url, callbacks, undefined, { method: 'GET' }); }; - return {callback: resp}; + return { callback: resp }; }, eids: { 'hadronId': { diff --git a/modules/hadronRtdProvider.js b/modules/hadronRtdProvider.js index 0ff11de1a3e..216ef1336f6 100644 --- a/modules/hadronRtdProvider.js +++ b/modules/hadronRtdProvider.js @@ -5,13 +5,13 @@ * @module modules/hadronRtdProvider * @requires module:modules/realTimeData */ -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isFn, isStr, isArray, deepEqual, isPlainObject, logInfo} from '../src/utils.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { config } from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { isFn, isStr, isArray, deepEqual, isPlainObject, logInfo } from '../src/utils.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -24,7 +24,7 @@ const AU_GVLID = 561; const HADRON_JS_URL = 'https://cdn.hadronid.net/hadron.js'; const LS_TAM_KEY = 'auHadronId'; const RTD_LOCAL_NAME = 'auHadronRtd'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME }); /** * @param {string} url @@ -47,11 +47,11 @@ function mergeDeep(target, ...sources) { if (isPlainObject(target) && isPlainObject(source)) { for (const key in source) { if (isPlainObject(source[key])) { - if (!target[key]) Object.assign(target, {[key]: {}}); + if (!target[key]) Object.assign(target, { [key]: {} }); mergeDeep(target[key], source[key]); } else if (isArray(source[key])) { if (!target[key]) { - Object.assign(target, {[key]: source[key]}); + Object.assign(target, { [key]: source[key] }); } else if (isArray(target[key])) { source[key].forEach(obj => { let e = 1; @@ -67,7 +67,7 @@ function mergeDeep(target, ...sources) { }); } } else { - Object.assign(target, {[key]: source[key]}); + Object.assign(target, { [key]: source[key] }); } } } diff --git a/modules/harionBidAdapter.js b/modules/harionBidAdapter.js new file mode 100644 index 00000000000..40b1b8282b3 --- /dev/null +++ b/modules/harionBidAdapter.js @@ -0,0 +1,25 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'harion'; +const GVLID = 1406; +const AD_URL = 'https://east-api.harion-ma.com/pbjs'; + +export const spec = { + code: BIDDER_CODE, + gvlid: GVLID, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse: (serverResponse) => { + if (!serverResponse || !Array.isArray(serverResponse.body)) { + return []; + } + + return interpretResponse(serverResponse); + } +}; + +registerBidder(spec); diff --git a/modules/harionBidAdapter.md b/modules/harionBidAdapter.md new file mode 100644 index 00000000000..a2ec196eeab --- /dev/null +++ b/modules/harionBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: Harion Bidder Adapter +Module Type: Harion Bidder Adapter +Maintainer: adtech@markappmedia.site +``` + +# Description + +Connects to Harion exchange for bids. +Harion bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'harion', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'harion', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'harion', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` diff --git a/modules/humansecurityRtdProvider.js b/modules/humansecurityRtdProvider.js deleted file mode 100644 index aeb872beb8d..00000000000 --- a/modules/humansecurityRtdProvider.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * This module adds humansecurity provider to the real time data module - * - * The {@link module:modules/realTimeData} module is required - * The module will inject the HUMAN Security script into the context where Prebid.js is initialized, enriching bid requests with specific data to provide advanced protection against ad fraud and spoofing. - * @module modules/humansecurityRtdProvider - * @requires module:modules/realTimeData - */ - -import { submodule } from '../src/hook.js'; -import { - prefixLog, - mergeDeep, - generateUUID, - getWindowSelf, -} from '../src/utils.js'; -import { getRefererInfo } from '../src/refererDetection.js'; -import { getGlobal } from '../src/prebidGlobal.js'; -import { loadExternalScript } from '../src/adloader.js'; -import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; - -/** - * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule - * @typedef {import('../modules/rtdModule/index.js').SubmoduleConfig} SubmoduleConfig - * @typedef {import('../modules/rtdModule/index.js').UserConsentData} UserConsentData - */ - -const SUBMODULE_NAME = 'humansecurity'; -const SCRIPT_URL = 'https://sonar.script.ac/prebid/rtd.js'; - -const { logInfo, logWarn, logError } = prefixLog(`[${SUBMODULE_NAME}]:`); - -/** @type {string} */ -let clientId = ''; - -/** @type {boolean} */ -let verbose = false; - -/** @type {string} */ -let sessionId = ''; - -/** @type {Object} */ -let hmnsData = { }; - -/** - * Submodule registration - */ -function main() { - submodule('realTimeData', /** @type {RtdSubmodule} */ ({ - name: SUBMODULE_NAME, - - // - init: (config, userConsent) => { - try { - load(config); - return true; - } catch (err) { - logError('init', err.message); - return false; - } - }, - - getBidRequestData: onGetBidRequestData - })); -} - -/** - * Injects HUMAN Security script on the page to facilitate pre-bid signal collection. - * @param {SubmoduleConfig} config - */ -function load(config) { - // By default, this submodule loads the generic implementation script - // only identified by the referrer information. In the future, if publishers - // want to have analytics where their websites are grouped, they can request - // Client ID from HUMAN, pass it here, and it will enable advanced reporting - clientId = config?.params?.clientId || ''; - if (clientId && (typeof clientId !== 'string' || !/^\w{3,16}$/.test(clientId))) { - throw new Error(`The 'clientId' parameter must be a short alphanumeric string`); - } - - // Load/reset the state - verbose = !!config?.params?.verbose; - sessionId = generateUUID(); - hmnsData = {}; - - // We rely on prebid implementation to get the best domain possible here - // In some cases, it still might be null, though - const refDomain = getRefererInfo().domain || ''; - - // Once loaded, the implementation script will publish an API using - // the session ID value it was given in data attributes - const scriptAttrs = { 'data-sid': sessionId }; - const scriptUrl = `${SCRIPT_URL}?r=${refDomain}${clientId ? `&c=${clientId}` : ''}`; - - loadExternalScript(scriptUrl, MODULE_TYPE_RTD, SUBMODULE_NAME, onImplLoaded, null, scriptAttrs); -} - -/** - * The callback to loadExternalScript - * Establishes the bridge between this RTD submodule and the loaded implementation - */ -function onImplLoaded() { - // We then get a hold on this script using the knowledge of this session ID - const wnd = getWindowSelf(); - const impl = wnd[`sonar_${sessionId}`]; - if (typeof impl !== 'object' || typeof impl.connect !== 'function') { - verbose && logWarn('onload', 'Unable to access the implementation script'); - return; - } - - // And set up a bridge between the RTD submodule and the implementation. - // The first argument is used to identify the caller. - // The callback might be called multiple times to update the signals - // once more precise information is available. - impl.connect(getGlobal(), onImplMessage); -} - -/** - * The bridge function will be called by the implementation script - * to update the token information or report errors - * @param {Object} msg - */ -function onImplMessage(msg) { - if (typeof msg !== 'object') { - return; - } - - switch (msg.type) { - case 'hmns': { - hmnsData = mergeDeep({}, msg.data || {}); - break; - } - case 'error': { - logError('impl', msg.data || ''); - break; - } - case 'warn': { - verbose && logWarn('impl', msg.data || ''); - break; - } - case 'info': { - verbose && logInfo('impl', msg.data || ''); - break; - } - } -} - -/** - * onGetBidRequestData is called once per auction. - * Update the `ortb2Fragments` object with the data from the injected script. - * - * @param {Object} reqBidsConfigObj - * @param {function} callback - * @param {SubmoduleConfig} config - * @param {UserConsentData} userConsent - */ -function onGetBidRequestData(reqBidsConfigObj, callback, config, userConsent) { - // Add device.ext.hmns to the global ORTB data for all vendors to use - // At the time of writing this submodule, "hmns" is an object defined - // internally by humansecurity, and it currently contains "v1" field - // with a token that contains collected signals about this session. - mergeDeep(reqBidsConfigObj.ortb2Fragments.global, { device: { ext: { hmns: hmnsData } } }); - callback(); -} - -/** - * Exporting local (and otherwise encapsulated to this module) functions - * for testing purposes - */ -export const __TEST__ = { - SUBMODULE_NAME, - SCRIPT_URL, - main, - load, - onImplLoaded, - onImplMessage, - onGetBidRequestData -}; - -main(); diff --git a/modules/humansecurityRtdProvider.md b/modules/humansecurityRtdProvider.md index 6722319cbb5..fceb012e27c 100644 --- a/modules/humansecurityRtdProvider.md +++ b/modules/humansecurityRtdProvider.md @@ -23,7 +23,7 @@ sent within bid requests, and used for bot detection on the backend. * No incremental signals collected beyond existing HUMAN post-bid solution * Offsets negative impact from loss of granularity in IP and User Agent at bid time * Does not expose collected IVT signal to any party who doesn’t otherwise already have access to the same signal collected post-bid -* Does not introduce meaningful latency, as demonstrated in the Latency section +* Does not introduce meaningful latency * Comes at no additional cost to collect IVT signal and make it available at bid time * Leveraged to differentiate the invalid bid requests at device level, and cannot be used to identify a user or a device, thus preserving privacy. @@ -56,8 +56,8 @@ pbjs.setConfig({ }); ``` -It can be optionally parameterized, for example, to include client ID obtained from HUMAN, -should any advanced reporting be needed, or to have verbose output for troubleshooting: +Other parameters can also be provided. For example, a client ID obtained from HUMAN can +optionally be provided, or verbose output can be enabled for troubleshooting purposes: ```javascript pbjs.setConfig({ @@ -79,6 +79,7 @@ pbjs.setConfig({ | :--------------- | :------------ | :------------------------------------------------------------------ |:---------| | `clientId` | String | Should you need advanced reporting, contact [prebid@humansecurity.com](prebid@humansecurity.com) to receive client ID. | No | | `verbose` | Boolean | Only set to `true` if troubleshooting issues. | No | +| `perBidderOptOut` | string[] | Pass any bidder alias to opt-out from per-bidder signal generation. | No | ## Logging, latency and troubleshooting @@ -89,9 +90,6 @@ of type `ERROR`. With `verbose` parameter set to `true`, it may additionally: * Call `logWarning`, resulting in `auctionDebug` events of type `WARNING`, * Call `logInfo` with latency information. - * To observe these messages in console, Prebid.js must be run in - [debug mode](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#debugging) - - either by adding `?pbjs_debug=true` to your page's URL, or by configuring with `pbjs.setConfig({ debug: true });` Example output of the latency information: @@ -139,6 +137,7 @@ There are a few points that are worth being mentioned separately, to avoid confu the ever-evolving nature of the threat landscape without the publishers having to rebuild their Prebid.js frequently. * The signal collection script is also obfuscated, as a defense-in-depth measure in order to complicate tampering by bad actors, as are all similar scripts in the industry, which is something that cannot be accommodated by Prebid.js itself. +* The collected signals are encrypted before they are passed to bid adapters and can only be interpreted by HUMAN backend systems. ## Why is this approach an innovation? @@ -199,10 +198,14 @@ ensuring the value of the inventory. ## FAQ +### Is partnership with HUMAN required to use the submodule? + +No. Using this submodule does not require any prior communication with HUMAN or being a client of HUMAN. +It is free and usage of the submodule doesn’t automatically make a Publisher HUMAN client. + ### Is latency an issue? The HUMAN Security RTD submodule is designed to minimize any latency in the auction within normal SLAs. - ### Do publishers get any insight into how the measurement is judged? Having the The HUMAN Security RTD submodule be part of the prebid process will allow the publisher to have insight @@ -211,13 +214,10 @@ inventory to the buyer. ### How are privacy concerns addressed? -The HUMAN Security RTD submodule seeks to reduce the impacts from signal deprecation that are inevitable without -compromising privacy by avoiding re-identification. Each bid request is enriched with just enough signal -to identify if the traffic is invalid or not. - -By having the The HUMAN Security RTD submodule operate at the Prebid level, data can be controlled -and not as freely passed through the bidstream where it may be accessible to various unknown parties. +The HUMAN Security RTD submodule seeks to reduce the impacts of signal deprecation without compromising privacy. +Each bid request is enriched with just enough signal to identify if the traffic is invalid or not, and these +signals are encrypted before being included in bid requests to prevent misuse. Note: anti-fraud use cases typically have carve outs in laws and regulations to permit data collection essential for effective fraud mitigation, but this does not constitute legal advice and you should -consult your attorney when making data access decisions. +consult your attorney when making data access decisions. \ No newline at end of file diff --git a/modules/humansecurityRtdProvider.ts b/modules/humansecurityRtdProvider.ts new file mode 100644 index 00000000000..96b99eadfb7 --- /dev/null +++ b/modules/humansecurityRtdProvider.ts @@ -0,0 +1,204 @@ +/** + * This module adds humansecurity provider to the real time data module + * + * The {@link module:modules/realTimeData} module is required + * The module will inject the HUMAN Security script into the context where Prebid.js is initialized, enriching bid requests with specific + * data to provide advanced protection against ad fraud and spoofing. + * @module modules/humansecurityRtdProvider + * @requires module:modules/realTimeData + */ +import { submodule } from '../src/hook.js'; +import { prefixLog, generateUUID, getWindowSelf } from '../src/utils.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { getGlobal, PrebidJS } from '../src/prebidGlobal.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; +import { AllConsentData } from '../src/consentHandler.ts'; +import type { RTDProvider, RTDProviderConfig, RtdProviderSpec } from './rtdModule/spec.ts'; +import type { StartAuctionOptions } from '../src/prebid.ts'; +import type { AuctionProperties } from '../src/auction.ts'; + +declare module './rtdModule/spec.ts' { + interface ProviderConfig { + humansecurity: { + params?: { + clientId?: string; + verbose?: boolean; + perBidderOptOut?: string[]; + }; + }; + } +} + +interface HumanSecurityImpl { + connect( + pbjs: PrebidJS, + callback: (m: string) => void | null, + config: RTDProviderConfig<'humansecurity'> + ): void; + + getBidRequestData( + reqBidsConfigObj: StartAuctionOptions, + callback: () => void, + config: RTDProviderConfig<'humansecurity'>, + userConsent: AllConsentData + ): void; + + onAuctionInitEvent( + pbjs: PrebidJS, + auctionDetails: AuctionProperties, + config: RTDProviderConfig<'humansecurity'>, + userConsent: AllConsentData + ): void; +} + +const SUBMODULE_NAME = 'humansecurity' as const; +const SCRIPT_URL = 'https://sonar.script.ac/prebid/rtd.js'; +const MODULE_VERSION = 1; + +const { logWarn, logError } = prefixLog(`[${SUBMODULE_NAME}]:`); + +let implRef: HumanSecurityImpl | null = null; +let clientId: string = ''; +let verbose: boolean = false; +let sessionId: string = ''; + +/** + * Injects HUMAN Security script on the page to facilitate pre-bid signal collection. + */ + +const load = (config: RTDProviderConfig<'humansecurity'>) => { + // Load implementation script and pass configuration parameters via data attributes + clientId = config?.params?.clientId || ''; + if (clientId && (typeof clientId !== 'string' || !/^\w{3,16}$/.test(clientId))) { + throw new Error(`The 'clientId' parameter must be a short alphanumeric string`); + } + + // Load/reset the state + verbose = !!config?.params?.verbose; + implRef = null; + sessionId = generateUUID(); + + // Get the best domain possible here, it still might be null + const refDomain = getRefererInfo().domain || ''; + + // Once loaded, the implementation script will publish an API using + // the session ID value it was given in data attributes + const scriptAttrs = { 'data-sid': sessionId }; + const scriptUrl = `${SCRIPT_URL}?r=${refDomain}${clientId ? `&c=${clientId}` : ''}&mv=${MODULE_VERSION}`; + + loadExternalScript(scriptUrl, MODULE_TYPE_RTD, SUBMODULE_NAME, () => onImplLoaded(config), null, scriptAttrs); +} + +/** + * Retrieves the implementation object created by the loaded script + * using the session ID as a key + */ + +const getImpl = () => { + // Use cached reference if already resolved + if (implRef && typeof implRef === 'object' && typeof implRef.connect === 'function') return implRef; + + // Attempt to resolve from window by session ID + const wnd = getWindowSelf(); + const impl: HumanSecurityImpl = wnd[`sonar_${sessionId}`]; + + if (typeof impl !== 'object' || typeof impl.connect !== 'function') { + verbose && logWarn('onload', 'Unable to access the implementation script'); + return; + } + implRef = impl; + return impl; +} + +/** + * The callback to loadExternalScript + * Establishes the bridge between this RTD submodule and the loaded implementation + */ + +const onImplLoaded = (config: RTDProviderConfig<'humansecurity'>) => { + const impl = getImpl(); + if (!impl) return; + + // And set up a bridge between the RTD submodule and the implementation. + impl.connect(getGlobal(), null, config); +} + +/** + * The bridge function will be called by the implementation script + * to update the token information or report errors + */ + +/** + * https://docs.prebid.org/dev-docs/add-rtd-submodule.html#getbidrequestdata + */ + +const getBidRequestData = ( + reqBidsConfigObj: StartAuctionOptions, + callback: () => void, + config: RtdProviderSpec<'humansecurity'>, + userConsent: AllConsentData +) => { + const impl = getImpl(); + if (!impl || typeof impl.getBidRequestData !== 'function') { + // Implementation not available; continue auction by invoking the callback. + callback(); + return; + } + + impl.getBidRequestData(reqBidsConfigObj, callback, config, userConsent); +} + +/** + * Event hooks + * https://docs.prebid.org/dev-docs/add-rtd-submodule.html#using-event-listeners + */ + +const onAuctionInitEvent = (auctionDetails: AuctionProperties, config: RTDProviderConfig<'humansecurity'>, userConsent: AllConsentData) => { + const impl = getImpl(); + if (!impl || typeof impl.onAuctionInitEvent !== 'function') return; + impl.onAuctionInitEvent(getGlobal(), auctionDetails, config, userConsent); +} + +/** + * Submodule registration + */ + +type RtdProviderSpecWithHooks

= RtdProviderSpec

& { + onAuctionInitEvent?: (auctionDetails: AuctionProperties, config: RTDProviderConfig

, userConsent: AllConsentData) => void; +}; + +const subModule: RtdProviderSpecWithHooks<'humansecurity'> = ({ + name: SUBMODULE_NAME, + init: (config, _userConsent) => { + try { + load(config); + return true; + } catch (err) { + const message = (err && typeof err === 'object' && 'message' in err) + ? (err as any).message + : String(err); + logError('init', message); + return false; + } + }, + getBidRequestData, + onAuctionInitEvent, +}); + +const registerSubModule = () => { submodule('realTimeData', subModule); } +registerSubModule(); + +/** + * Exporting local (and otherwise encapsulated to this module) functions + * for testing purposes + */ + +export const __TEST__ = { + SUBMODULE_NAME, + SCRIPT_URL, + main: registerSubModule, + load, + onImplLoaded, + getBidRequestData +}; diff --git a/modules/hybridBidAdapter.js b/modules/hybridBidAdapter.js index 1a9552c1754..24168e625d3 100644 --- a/modules/hybridBidAdapter.js +++ b/modules/hybridBidAdapter.js @@ -1,7 +1,7 @@ -import {_map, isArray} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {createRenderer, getMediaTypeFromBid, hasVideoMandatoryParams} from '../libraries/hybridVoxUtils/index.js'; +import { _map, isArray } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { createRenderer, getMediaTypeFromBid, hasVideoMandatoryParams } from '../libraries/hybridVoxUtils/index.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -52,8 +52,7 @@ function buildBid(bidData) { currency: bidData.currency, netRevenue: true, ttl: TTL, - meta: { - advertiserDomains: bidData.advertiserDomains || []} + meta: { advertiserDomains: bidData.advertiserDomains || [] } }; if (bidData.placement === PLACEMENT_TYPE_VIDEO) { diff --git a/modules/iasRtdProvider.js b/modules/iasRtdProvider.js index 3f0b8513299..9205d6c4561 100644 --- a/modules/iasRtdProvider.js +++ b/modules/iasRtdProvider.js @@ -1,9 +1,9 @@ -import {submodule} from '../src/hook.js'; +import { submodule } from '../src/hook.js'; import * as utils from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { ajax } from '../src/ajax.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { mergeDeep } from '../src/utils.js'; /** diff --git a/modules/id5AnalyticsAdapter.js b/modules/id5AnalyticsAdapter.js index dca244bb317..033483157b4 100644 --- a/modules/id5AnalyticsAdapter.js +++ b/modules/id5AnalyticsAdapter.js @@ -1,8 +1,8 @@ import buildAdapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {EVENTS} from '../src/constants.js'; +import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {ajax} from '../src/ajax.js'; -import {compressDataWithGZip, isGzipCompressionSupported, logError, logInfo} from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { compressDataWithGZip, isGzipCompressionSupported, logError, logInfo } from '../src/utils.js'; import * as events from '../src/events.js'; const { @@ -26,7 +26,7 @@ const PBJS_VERSION = 'v' + '$prebid.version$'; const ID5_REDACTED = '__ID5_REDACTED__'; const isArray = Array.isArray; -const id5Analytics = Object.assign(buildAdapter({analyticsType: 'endpoint'}), { +const id5Analytics = Object.assign(buildAdapter({ analyticsType: 'endpoint' }), { eventsToTrack: STANDARD_EVENTS_TO_TRACK, track: (event) => { diff --git a/modules/id5IdSystem.js b/modules/id5IdSystem.js index d8f553c6ae0..bce8e5bcb6e 100644 --- a/modules/id5IdSystem.js +++ b/modules/id5IdSystem.js @@ -8,6 +8,7 @@ import { deepAccess, deepClone, + deepEqual, deepSetValue, isEmpty, isEmptyStr, @@ -16,13 +17,13 @@ import { logInfo, logWarn } from '../src/utils.js'; -import {fetch} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; -import {PbPromise} from '../src/utils/promise.js'; -import {loadExternalScript} from '../src/adloader.js'; +import { fetch } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { PbPromise } from '../src/utils/promise.js'; +import { loadExternalScript } from '../src/adloader.js'; /** * @typedef {import('../modules/userId/spec.ts').IdProviderSpec} Submodule @@ -39,7 +40,7 @@ const ID5_API_CONFIG_URL = 'https://id5-sync.com/api/config/prebid'; const ID5_DOMAIN = 'id5-sync.com'; const TRUE_LINK_SOURCE = 'true-link-id5-sync.com'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** * @typedef {Object} Id5Response @@ -118,6 +119,7 @@ export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleNam * @property {Array} [segments] - A list of segments to push to partners. Supported only in multiplexing. * @property {boolean} [disableUaHints] - When true, look up of high entropy values through user agent hints is disabled. * @property {string} [gamTargetingPrefix] - When set, the GAM targeting tags will be set and use the specified prefix, for example 'id5'. + * @property {boolean} [exposeTargeting] - When set, the ID5 targeting consumer mechanism will be enabled. */ /** @@ -245,7 +247,7 @@ export const id5IdSubmodule = { responseObj.euid = { uid: ext.euid.uids[0].id, source: ext.euid.source, - ext: {provider: ID5_DOMAIN} + ext: { provider: ID5_DOMAIN } }; } @@ -308,7 +310,7 @@ export const id5IdSubmodule = { cbFunction(); }); }; - return {callback: resp}; + return { callback: resp }; }, /** @@ -325,14 +327,14 @@ export const id5IdSubmodule = { extendId(config, consentData, cacheIdObj) { if (!hasWriteConsentToLocalStorage(consentData?.gdpr)) { logInfo(LOG_PREFIX + 'No consent given for ID5 local storage writing, skipping nb increment.'); - return {id: cacheIdObj}; + return { id: cacheIdObj }; } if (getPartnerResponse(cacheIdObj, config.params)) { // response for partner is present logInfo(LOG_PREFIX + 'using cached ID', cacheIdObj); const updatedObject = deepClone(cacheIdObj); const responseToUpdate = getPartnerResponse(updatedObject, config.params); responseToUpdate.nbPage = incrementNb(responseToUpdate); - return {id: updatedObject}; + return { id: updatedObject }; } else { logInfo(LOG_PREFIX + ' refreshing ID. Cached object does not have ID for partner', cacheIdObj); return this.getId(config, consentData, cacheIdObj); @@ -419,7 +421,7 @@ export class IdFetchFlow { const extensionsUrl = extensionsCallConfig.url; const method = extensionsCallConfig.method || 'GET'; const body = method === 'GET' ? undefined : JSON.stringify(extensionsCallConfig.body || {}); - const response = await fetch(extensionsUrl, {method, body}); + const response = await fetch(extensionsUrl, { method, body }); if (!response.ok) { throw new Error('Error while calling extensions endpoint: ', response); } @@ -436,7 +438,7 @@ export class IdFetchFlow { ...additionalData, extensions: extensionsData }); - const response = await fetch(fetchUrl, {method: 'POST', body, credentials: 'include'}); + const response = await fetch(fetchUrl, { method: 'POST', body, credentials: 'include' }); if (!response.ok) { throw new Error('Error while calling fetch endpoint: ', response); } @@ -451,7 +453,7 @@ export class IdFetchFlow { const referer = getRefererInfo(); const signature = this.cacheIdObj ? this.cacheIdObj.signature : undefined; const nbPage = incrementNb(this.cacheIdObj); - const trueLinkInfo = window.id5Bootstrap ? window.id5Bootstrap.getTrueLinkInfo() : {booted: false}; + const trueLinkInfo = window.id5Bootstrap ? window.id5Bootstrap.getTrueLinkInfo() : { booted: false }; const data = { 'partner': params.partner, @@ -490,7 +492,7 @@ export class IdFetchFlow { if (params.provider !== undefined && !isEmptyStr(params.provider)) { data.provider = params.provider; } - const abTestingConfig = params.abTesting || {enabled: false}; + const abTestingConfig = params.abTesting || { enabled: false }; if (abTestingConfig.enabled) { data.ab_testing = { @@ -569,17 +571,30 @@ function incrementNb(cachedObj) { } function updateTargeting(fetchResponse, config) { - if (config.params.gamTargetingPrefix) { - const tags = fetchResponse.tags; - if (tags) { - window.googletag = window.googletag || {cmd: []}; + const tags = fetchResponse.tags; + if (tags) { + if (config.params.gamTargetingPrefix) { + window.googletag = window.googletag || { cmd: [] }; window.googletag.cmd = window.googletag.cmd || []; window.googletag.cmd.push(() => { for (const tag in tags) { - window.googletag.pubads().setTargeting(config.params.gamTargetingPrefix + '_' + tag, tags[tag]); + window.googletag.setConfig({ targeting: { [config.params.gamTargetingPrefix + '_' + tag]: tags[tag] } }); } }); } + + if (config.params.exposeTargeting && !deepEqual(window.id5tags?.tags, tags)) { + window.id5tags = window.id5tags || { cmd: [] }; + window.id5tags.cmd = window.id5tags.cmd || []; + window.id5tags.cmd.forEach(tagsCallback => { + setTimeout(() => tagsCallback(tags), 0); + }); + window.id5tags.cmd.push = function (tagsCallback) { + tagsCallback(tags) + Array.prototype.push.call(window.id5tags.cmd, tagsCallback); + }; + window.id5tags.tags = tags + } } } diff --git a/modules/id5IdSystem.md b/modules/id5IdSystem.md index 363dd02e831..aaf34fa4054 100644 --- a/modules/id5IdSystem.md +++ b/modules/id5IdSystem.md @@ -33,7 +33,8 @@ pbjs.setConfig({ }, disableExtensions: false,// optional canCookieSync: true, // optional, has effect only when externalModuleUrl is used - gamTargetingPrefix: "id5" // optional, when set the ID5 module will set gam targeting paramaters with this prefix + gamTargetingPrefix: "id5", // optional, when set the ID5 module will set gam targeting paramaters with this prefix + exposeTargeting: false // optional, when set the ID5 module will execute `window.id5tags.cmd` callbacks for custom targeting tags }, storage: { type: 'html5', // "html5" is the required storage type @@ -47,25 +48,26 @@ pbjs.setConfig({ }); ``` -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| --- | -| name | Required | String | The name of this module: `"id5Id"` | `"id5Id"` | -| params | Required | Object | Details for the ID5 ID. | | -| params.partner | Required | Number | This is the ID5 Partner Number obtained from registering with ID5. | `173` | -| params.externalModuleUrl | Optional | String | The URL for the id5-prebid external module. It is recommended to use the latest version at the URL in the example. Source code available [here](https://github.com/id5io/id5-api.js/blob/master/src/id5PrebidModule.js). | https://cdn.id5-sync.com/api/1.0/id5PrebidModule.js -| params.pd | Optional | String | Partner-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/en/identitycloud/retrieve-id5-ids/passing-partner-data-to-id5) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` | -| params.provider | Optional | String | An identifier provided by ID5 to technology partners who manage Prebid setups on behalf of publishers. Reach out to [ID5](mailto:prebid@id5.io) if you have questions about this parameter | `pubmatic-identity-hub` | -| params.abTesting | Optional | Object | Allows publishers to easily run an A/B Test. If enabled and the user is in the Control Group, the ID5 ID will NOT be exposed to bid adapters for that request | Disabled by default | -| params.abTesting.enabled | Optional | Boolean | Set this to `true` to turn on this feature | `true` or `false` | -| params.abTesting.controlGroupPct | Optional | Number | Must be a number between `0.0` and `1.0` (inclusive) and is used to determine the percentage of requests that fall into the control group (and thus not exposing the ID5 ID). For example, a value of `0.20` will result in 20% of requests without an ID5 ID and 80% with an ID. | `0.1` | -| params.disableExtensions | Optional | Boolean | Set this to `true` to force turn off extensions call. Default `false` | `true` or `false` | -| params.canCookieSync | Optional | Boolean | Set this to `true` to enable cookie syncing with other ID5 partners. See [our documentation](https://wiki.id5.io/docs/initiate-cookie-sync-to-id5) for details. Default `false` | `true` or `false` | +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------| +| name | Required | String | The name of this module: `"id5Id"` | `"id5Id"` | +| params | Required | Object | Details for the ID5 ID. | | +| params.partner | Required | Number | This is the ID5 Partner Number obtained from registering with ID5. | `173` | +| params.externalModuleUrl | Optional | String | The URL for the id5-prebid external module. It is recommended to use the latest version at the URL in the example. Source code available [here](https://github.com/id5io/id5-api.js/blob/master/src/id5PrebidModule.js). | https://cdn.id5-sync.com/api/1.0/id5PrebidModule.js +| params.pd | Optional | String | Partner-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/en/identitycloud/retrieve-id5-ids/passing-partner-data-to-id5) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` | +| params.provider | Optional | String | An identifier provided by ID5 to technology partners who manage Prebid setups on behalf of publishers. Reach out to [ID5](mailto:prebid@id5.io) if you have questions about this parameter | `pubmatic-identity-hub` | +| params.abTesting | Optional | Object | Allows publishers to easily run an A/B Test. If enabled and the user is in the Control Group, the ID5 ID will NOT be exposed to bid adapters for that request | Disabled by default | +| params.abTesting.enabled | Optional | Boolean | Set this to `true` to turn on this feature | `true` or `false` | +| params.abTesting.controlGroupPct | Optional | Number | Must be a number between `0.0` and `1.0` (inclusive) and is used to determine the percentage of requests that fall into the control group (and thus not exposing the ID5 ID). For example, a value of `0.20` will result in 20% of requests without an ID5 ID and 80% with an ID. | `0.1` | +| params.disableExtensions | Optional | Boolean | Set this to `true` to force turn off extensions call. Default `false` | `true` or `false` | +| params.canCookieSync | Optional | Boolean | Set this to `true` to enable cookie syncing with other ID5 partners. See [our documentation](https://wiki.id5.io/docs/initiate-cookie-sync-to-id5) for details. Default `false` | `true` or `false` | | params.gamTargetingPrefix | Optional | String | When this parameter is set the ID5 module will set appropriate GAM pubads targeting tags | `id5` | -| storage | Required | Object | Storage settings for how the User ID module will cache the ID5 ID locally | | -| storage.type | Required | String | This is where the results of the user ID will be stored. ID5 **requires** `"html5"`. | `"html5"` | -| storage.name | Required | String | The name of the local storage where the user ID will be stored. ID5 **requires** `"id5id"`. | `"id5id"` | -| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. ID5 recommends `90`. | `90` | -| storage.refreshInSeconds | Optional | Integer | How many seconds until the ID5 ID will be refreshed. ID5 strongly recommends 2 hours between refreshes | `7200` | +| params.exposeTargeting | Optional | Boolean | When this parameter is set the ID5 module will execute `window.id5tags.cmd` callbacks for custom targeting tags | `false` | +| storage | Required | Object | Storage settings for how the User ID module will cache the ID5 ID locally | | +| storage.type | Required | String | This is where the results of the user ID will be stored. ID5 **requires** `"html5"`. | `"html5"` | +| storage.name | Required | String | The name of the local storage where the user ID will be stored. ID5 **requires** `"id5id"`. | `"id5id"` | +| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. ID5 recommends `90`. | `90` | +| storage.refreshInSeconds | Optional | Integer | How many seconds until the ID5 ID will be refreshed. ID5 strongly recommends 2 hours between refreshes | `7200` | **ATTENTION:** As of Prebid.js v4.14.0, ID5 requires `storage.type` to be `"html5"` and `storage.name` to be `"id5id"`. Using other values will display a warning today, but in an upcoming release, it will prevent the ID5 module from loading. This change is to ensure the ID5 module in Prebid.js interoperates properly with the [ID5 API](https://github.com/id5io/id5-api.js) and to reduce the size of publishers' first-party cookies that are sent to their web servers. If you have any questions, please reach out to us at [prebid@id5.io](mailto:prebid@id5.io). diff --git a/modules/idImportLibrary.js b/modules/idImportLibrary.js index b3e0be4505c..248f999f5bd 100644 --- a/modules/idImportLibrary.js +++ b/modules/idImportLibrary.js @@ -235,7 +235,7 @@ function postData() { syncPayload.uids = userIds; const payloadString = JSON.stringify(syncPayload); _logInfo(payloadString); - ajax(conf.url, syncCallback(), payloadString, {method: 'POST', withCredentials: true}); + ajax(conf.url, syncCallback(), payloadString, { method: 'POST', withCredentials: true }); } function associateIds() { diff --git a/modules/identityLinkIdSystem.js b/modules/identityLinkIdSystem.js index 0f02e40a383..6d4442f2fc9 100644 --- a/modules/identityLinkIdSystem.js +++ b/modules/identityLinkIdSystem.js @@ -8,8 +8,8 @@ import * as utils from '../src/utils.js' import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -20,7 +20,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; const MODULE_NAME = 'identityLink'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); const liverampEnvelopeName = '_lr_env'; @@ -58,7 +58,7 @@ export const identityLinkSubmodule = { utils.logError('identityLink: requires partner id to be defined'); return; } - const {gdpr, gpp: gppData} = consentData ?? {}; + const { gdpr, gpp: gppData } = consentData ?? {}; const hasGdpr = (gdpr && typeof gdpr.gdprApplies === 'boolean' && gdpr.gdprApplies) ? 1 : 0; const gdprConsentString = hasGdpr ? gdpr.consentString : ''; // use protocol relative urls for http or https diff --git a/modules/idxBidAdapter.js b/modules/idxBidAdapter.js index 12adb4058ae..af2e9c31210 100644 --- a/modules/idxBidAdapter.js +++ b/modules/idxBidAdapter.js @@ -5,7 +5,7 @@ import { interpretResponse } from '../libraries/precisoUtils/bidUtils.js'; const BIDDER_CODE = 'idx' const ENDPOINT_URL = 'https://dev-event.dxmdp.com/rest/api/v1/bid' -const SUPPORTED_MEDIA_TYPES = [ BANNER ] +const SUPPORTED_MEDIA_TYPES = [BANNER] export const spec = { code: BIDDER_CODE, diff --git a/modules/idxIdSystem.js b/modules/idxIdSystem.js index da8230dbe29..55624faac0e 100644 --- a/modules/idxIdSystem.js +++ b/modules/idxIdSystem.js @@ -6,8 +6,8 @@ */ import { isStr, isPlainObject, logError } from '../src/utils.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -16,7 +16,7 @@ import {MODULE_TYPE_UID} from '../src/activities/modules.js'; const IDX_MODULE_NAME = 'idx'; const IDX_COOKIE_NAME = '_idx'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: IDX_MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: IDX_MODULE_NAME }); function readIDxFromCookie() { return storage.cookiesAreEnabled ? storage.getCookie(IDX_COOKIE_NAME) : null; diff --git a/modules/illuminBidAdapter.js b/modules/illuminBidAdapter.js index 0e76e471f4b..37d48e1626f 100644 --- a/modules/illuminBidAdapter.js +++ b/modules/illuminBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { isBidRequestValid, createUserSyncGetter, createInterpretResponseFn, createBuildRequestsFn } from '../libraries/vidazooUtils/bidderUtils.js'; @@ -9,7 +9,7 @@ const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'illumin'; const BIDDER_VERSION = '1.0.0'; const GVLID = 149; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.illumin.com`; diff --git a/modules/imRtdProvider.js b/modules/imRtdProvider.js index 46573a81c15..5052b4c12a6 100644 --- a/modules/imRtdProvider.js +++ b/modules/imRtdProvider.js @@ -4,10 +4,10 @@ * @module modules/imRtdProvider * @requires module:modules/realTimeData */ -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js' -import {getStorageManager} from '../src/storageManager.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js' +import { getStorageManager } from '../src/storageManager.js'; import { deepSetValue, deepAccess, @@ -17,8 +17,8 @@ import { logInfo, isFn } from '../src/utils.js' -import {submodule} from '../src/hook.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -32,7 +32,7 @@ const segmentsMaxAge = 3600000; // 1 hour (30 * 60 * 1000) const uidMaxAge = 1800000; // 30 minites (30 * 60 * 1000) const vidMaxAge = 97200000000; // 37 months ((365 * 3 + 30) * 24 * 60 * 60 * 1000) -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: submoduleName}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: submoduleName }); function setImDataInCookie(value) { storage.setCookie( @@ -103,7 +103,7 @@ export function getCustomBidderFunction(config, bidder) { */ export function setRealTimeData(bidConfig, moduleConfig, data) { const adUnits = bidConfig.adUnits || getGlobal().adUnits; - const utils = {deepSetValue, deepAccess, logInfo, logError, mergeDeep}; + const utils = { deepSetValue, deepAccess, logInfo, logError, mergeDeep }; if (data.im_segments) { const segments = getSegments(data.im_segments, moduleConfig); @@ -112,7 +112,7 @@ export function setRealTimeData(bidConfig, moduleConfig, data) { deepSetValue(ortb2, 'user.ext.data.im_uid', data.im_uid); if (moduleConfig.params.setGptKeyValues || !moduleConfig.params.hasOwnProperty('setGptKeyValues')) { - window.googletag = window.googletag || {cmd: []}; + window.googletag = window.googletag || { cmd: [] }; window.googletag.cmd = window.googletag.cmd || []; window.googletag.cmd.push(() => { window.googletag.pubads().setTargeting('im_segments', segments); @@ -165,7 +165,7 @@ export function getRealTimeData(reqBidsConfigObj, onDone, moduleConfig) { } if (sids !== null) { - setRealTimeData(reqBidsConfigObj, moduleConfig, {im_uid: uid, im_segments: parsedSids}); + setRealTimeData(reqBidsConfigObj, moduleConfig, { im_uid: uid, im_segments: parsedSids }); onDone(); alreadyDone = true; } @@ -175,7 +175,7 @@ export function getRealTimeData(reqBidsConfigObj, onDone, moduleConfig) { apiUrl, getApiCallback(reqBidsConfigObj, alreadyDone ? undefined : onDone, moduleConfig), undefined, - {method: 'GET', withCredentials: true} + { method: 'GET', withCredentials: true } ); } } @@ -212,7 +212,7 @@ export function getApiCallback(reqBidsConfigObj, onDone, moduleConfig) { } if (parsedResponse.segments) { - setRealTimeData(reqBidsConfigObj, moduleConfig, {im_uid: parsedResponse.uid, im_segments: parsedResponse.segments}); + setRealTimeData(reqBidsConfigObj, moduleConfig, { im_uid: parsedResponse.uid, im_segments: parsedResponse.segments }); storage.setDataInLocalStorage(imRtdLocalName, parsedResponse.segments); storage.setDataInLocalStorage(`${imRtdLocalName}_mt`, new Date(timestamp()).toUTCString()); } diff --git a/modules/impactifyBidAdapter.js b/modules/impactifyBidAdapter.js index 49ffe99245d..8ecdca972d3 100644 --- a/modules/impactifyBidAdapter.js +++ b/modules/impactifyBidAdapter.js @@ -1,6 +1,6 @@ 'use strict'; -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, deepSetValue, generateUUID, getWinDimensions, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; diff --git a/modules/improvedigitalBidAdapter.js b/modules/improvedigitalBidAdapter.js index 3846794f7cc..2fbff040159 100644 --- a/modules/improvedigitalBidAdapter.js +++ b/modules/improvedigitalBidAdapter.js @@ -1,11 +1,11 @@ -import {deepAccess, deepSetValue, getBidIdParameter, getUniqueIdentifierStr, logWarn, mergeDeep} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {convertCurrency} from '../libraries/currencyUtils/currency.js'; +import { deepAccess, deepSetValue, getBidIdParameter, getUniqueIdentifierStr, logWarn, mergeDeep } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { convertCurrency } from '../libraries/currencyUtils/currency.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -67,7 +67,7 @@ export const spec = { * @return {Array} An array of bids which were nested inside the server. */ interpretResponse(serverResponse, { ortbRequest }) { - return CONVERTER.fromORTB({request: ortbRequest, response: serverResponse.body}).bids; + return CONVERTER.fromORTB({ request: ortbRequest, response: serverResponse.body }).bids; }, /** @@ -139,7 +139,7 @@ export const CONVERTER = ortbConverter({ ttl: CREATIVE_TTL, nativeRequest: { eventtrackers: [ - {event: 1, methods: [1, 2]}, + { event: 1, methods: [1, 2] }, ] } }, @@ -190,7 +190,7 @@ export const CONVERTER = ortbConverter({ if (!bid.adm || !bid.price || bid.hasOwnProperty('errorCode')) { return; } - const {bidRequest} = context; + const { bidRequest } = context; context.mediaType = (() => { const requestMediaTypes = Object.keys(bidRequest.mediaTypes); if (requestMediaTypes.length === 1) return requestMediaTypes[0]; @@ -227,8 +227,8 @@ export const CONVERTER = ortbConverter({ // override to disregard banner.sizes if usePrebidSizes is false if (!bidRequest.mediaTypes[BANNER]) return; if (config.getConfig('improvedigital.usePrebidSizes') === false) { - const banner = Object.assign({}, bidRequest.mediaTypes[BANNER], {sizes: null}); - bidRequest = {...bidRequest, mediaTypes: {[BANNER]: banner}} + const banner = Object.assign({}, bidRequest.mediaTypes[BANNER], { sizes: null }); + bidRequest = { ...bidRequest, mediaTypes: { [BANNER]: banner } } } fillImpBanner(imp, bidRequest, context); }, @@ -236,13 +236,13 @@ export const CONVERTER = ortbConverter({ // override to use video params from both mediaTypes.video and bidRequest.params.video if (!bidRequest.mediaTypes[VIDEO]) return; const video = Object.assign( - {mimes: VIDEO_PARAMS.DEFAULT_MIMES}, + { mimes: VIDEO_PARAMS.DEFAULT_MIMES }, bidRequest.mediaTypes[VIDEO], bidRequest.params?.video ) fillImpVideo( imp, - {...bidRequest, mediaTypes: {[VIDEO]: video}}, + { ...bidRequest, mediaTypes: { [VIDEO]: video } }, context ); deepSetValue(imp, 'ext.is_rewarded_inventory', (video.rewarded === 1 || deepAccess(video, 'ext.rewarded') === 1) || undefined); @@ -274,7 +274,7 @@ const ID_REQUEST = { } function formatRequest(bidRequests, publisherId, extendMode) { - const ortbRequest = CONVERTER.toORTB({bidRequests, bidderRequest, context: {extendMode}}); + const ortbRequest = CONVERTER.toORTB({ bidRequests, bidderRequest, context: { extendMode } }); return { method: 'POST', url: adServerUrl(extendMode, publisherId), diff --git a/modules/imuIdSystem.js b/modules/imuIdSystem.js index 52fdb099e31..c9f57cbfaae 100644 --- a/modules/imuIdSystem.js +++ b/modules/imuIdSystem.js @@ -19,7 +19,7 @@ import { getRefererInfo } from '../src/refererDetection.js'; const MODULE_NAME = 'imuid'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); export const storageKey = '__im_uid'; export const storagePpKey = '__im_ppid'; @@ -112,7 +112,7 @@ export function getApiCallback(callback) { export function callImuidApi(apiUrl) { return function (callback) { - ajax(apiUrl, getApiCallback(callback), undefined, {method: 'GET', withCredentials: true}); + ajax(apiUrl, getApiCallback(callback), undefined, { method: 'GET', withCredentials: true }); }; } @@ -156,7 +156,7 @@ export const imuIdSubmodule = { } if (!localData.id) { - return {callback: callImuidApi(apiUrl)}; + return { callback: callImuidApi(apiUrl) }; } if (localData.expired) { callImuidApi(apiUrl)(); diff --git a/modules/insticatorBidAdapter.js b/modules/insticatorBidAdapter.js index 447947e43a4..2455d96fed2 100644 --- a/modules/insticatorBidAdapter.js +++ b/modules/insticatorBidAdapter.js @@ -1,11 +1,11 @@ -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepAccess, generateUUID, logError, isArray, isInteger, isArrayOfNums, deepSetValue, isFn, logWarn, getWinDimensions} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepAccess, generateUUID, logError, isArray, isInteger, isArrayOfNums, deepSetValue, isFn, logWarn, getWinDimensions } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; const BIDDER_CODE = 'insticator'; -const ENDPOINT = 'https://ex.ingage.tech/v1/openrtb'; // production endpoint +const ENDPOINT = 'https://ex.ingage.tech/v1/openrtb'; const USER_ID_KEY = 'hb_insticator_uid'; const USER_ID_COOKIE_EXP = 2592000000; // 30 days const BID_TTL = 300; // 5 minutes @@ -29,7 +29,16 @@ export const OPTIONAL_VIDEO_PARAMS = { 'playbackend': (value) => isInteger(value) && [1, 2, 3].includes(value), 'delivery': (value) => isArrayOfNums(value), 'pos': (value) => isInteger(value) && [0, 1, 2, 3, 4, 5, 6, 7].includes(value), - 'api': (value) => isArrayOfNums(value)}; + 'api': (value) => isArrayOfNums(value), + // ORTB 2.6 video parameters + 'podid': (value) => typeof value === 'string' && value.length > 0, + 'podseq': (value) => isInteger(value) && value >= 0, + 'poddur': (value) => isInteger(value) && value > 0, + 'slotinpod': (value) => isInteger(value) && [-1, 0, 1, 2].includes(value), + 'mincpmpersec': (value) => typeof value === 'number' && value > 0, + 'maxseq': (value) => isInteger(value) && value > 0, + 'rqddurs': (value) => isArrayOfNums(value) && value.every(v => v > 0), +}; const ORTB_SITE_FIRST_PARTY_DATA = { 'cat': v => Array.isArray(v) && v.every(c => typeof c === 'string'), @@ -41,7 +50,7 @@ const ORTB_SITE_FIRST_PARTY_DATA = { 'keywords': v => typeof v === 'string', } -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); config.setDefaults({ insticator: { @@ -106,7 +115,7 @@ function buildVideo(bidRequest) { const context = deepAccess(bidRequest, 'mediaTypes.video.context'); if (!h && !w && playerSize) { - ({w, h} = parsePlayerSizeToWidthHeight(playerSize, w, h)); + ({ w, h } = parsePlayerSizeToWidthHeight(playerSize, w, h)); } const bidRequestVideo = deepAccess(bidRequest, 'mediaTypes.video'); @@ -114,11 +123,11 @@ function buildVideo(bidRequest) { const optionalParams = {}; for (const param in OPTIONAL_VIDEO_PARAMS) { - if (bidRequestVideo[param] && OPTIONAL_VIDEO_PARAMS[param](bidRequestVideo[param])) { + if (bidRequestVideo[param] != null && OPTIONAL_VIDEO_PARAMS[param](bidRequestVideo[param])) { optionalParams[param] = bidRequestVideo[param]; } // remove invalid optional params from bidder specific overrides - if (videoBidderParams[param] && !OPTIONAL_VIDEO_PARAMS[param](videoBidderParams[param])) { + if (videoBidderParams[param] != null && !OPTIONAL_VIDEO_PARAMS[param](videoBidderParams[param])) { delete videoBidderParams[param]; } } @@ -205,7 +214,7 @@ function buildImpression(bidRequest) { } else { const sizes = deepAccess(bidRequest, 'mediaTypes.banner.format'); if (sizes && sizes.length > 0) { - const {w: width, h: height} = sizes[0]; + const { w: width, h: height } = sizes[0]; _size = [width, height]; } } @@ -405,7 +414,7 @@ function buildRequest(validBidRequests, bidderRequest) { if (params) { req.ext = { - insticator: {...req.ext.insticator, ...params}, + insticator: { ...req.ext.insticator, ...params }, }; } @@ -442,8 +451,9 @@ function buildRequest(validBidRequests, bidderRequest) { return req; } -function buildBid(bid, bidderRequest) { +function buildBid(bid, bidderRequest, seatbid) { const originalBid = ((bidderRequest.bids) || []).find((b) => b.bidId === bid.impid); + let meta = {} if (bid.ext && bid.ext.meta) { @@ -454,27 +464,79 @@ function buildBid(bid, bidderRequest) { meta.advertiserDomains = bid.adomain } + // ORTB 2.6: Add category support + if (bid.cat && Array.isArray(bid.cat) && bid.cat.length > 0) { + meta.primaryCatId = bid.cat[0]; + if (bid.cat.length > 1) { + meta.secondaryCatIds = bid.cat.slice(1); + } + } + + // ORTB 2.6: Add seat from seatbid + if (seatbid && seatbid.seat) { + meta.seat = seatbid.seat; + } + + // ORTB 2.6: Add creative attributes + if (bid.attr && Array.isArray(bid.attr)) { + meta.attr = bid.attr; + } + + // Determine media type using multiple signals let mediaType = 'banner'; - if (bid.adm && bid.adm.includes(' 0 ? Math.min(bid.exp, configTTL) : configTTL; + const bidResponse = { requestId: bid.impid, creativeId: bid.crid, cpm: bid.price, currency: 'USD', netRevenue: true, - ttl: bid.exp || config.getConfig('insticator.bidTTL') || BID_TTL, + ttl: ttl, width: bid.w, height: bid.h, mediaType: mediaType, ad: bid.adm, - adUnitCode: originalBid.adUnitCode, - ...(Object.keys(meta).length > 0 ? {meta} : {}) + adUnitCode: originalBid?.adUnitCode, + ...(Object.keys(meta).length > 0 ? { meta } : {}) }; + // ORTB 2.6: Add deal ID + if (bid.dealid) { + bidResponse.dealId = bid.dealid; + } + + // ORTB 2.6: Add billing URL for billing notification + if (bid.burl) { + bidResponse.burl = bid.burl; + } + + // ORTB 2.6: Add notice URL for win notification + if (bid.nurl) { + bidResponse.nurl = bid.nurl; + } + if (mediaType === 'video') { bidResponse.vastXml = bid.adm; + + // ORTB 2.6: Add video duration for adpod support + if (bid.dur && isInteger(bid.dur) && bid.dur > 0) { + bidResponse.video = bidResponse.video || {}; + bidResponse.video.durationSeconds = bid.dur; + } } // Inticator bid adaptor only returns `vastXml` for video bids. No VastUrl or videoCache. @@ -493,7 +555,7 @@ function buildBid(bid, bidderRequest) { } function buildBidSet(seatbid, bidderRequest) { - return seatbid.bid.map((bid) => buildBid(bid, bidderRequest)); + return seatbid.bid.map((bid) => buildBid(bid, bidderRequest, seatbid)); } function validateSize(size) { @@ -567,7 +629,7 @@ function validateVideo(bid) { const playerSize = deepAccess(bid, 'mediaTypes.video.playerSize'); if (!h && !w && playerSize) { - ({w, h} = parsePlayerSizeToWidthHeight(playerSize, w, h)); + ({ w, h } = parsePlayerSizeToWidthHeight(playerSize, w, h)); } const videoSize = [w, h]; @@ -631,7 +693,7 @@ function parsePlayerSizeToWidthHeight(playerSize, w, h) { export const spec = { code: BIDDER_CODE, gvlid: GVLID, - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function (bid) { return ( @@ -652,9 +714,19 @@ export const spec = { if (deepAccess(validBidRequests[0], 'params.bid_endpoint_request_url')) { endpointUrl = deepAccess(validBidRequests[0], 'params.bid_endpoint_request_url').replace(/^http:/, 'https:'); } + + // Add publisherId as query parameter if present and non-empty + const publisherId = deepAccess(validBidRequests[0], 'params.publisherId'); + if (publisherId && publisherId.trim() !== '') { + const urlObj = new URL(endpointUrl); + urlObj.searchParams.set('publisherId', publisherId); + endpointUrl = urlObj.toString(); + } } if (validBidRequests.length > 0) { + const ortbRequest = buildRequest(validBidRequests, bidderRequest); + requests.push({ method: 'POST', url: endpointUrl, @@ -662,7 +734,7 @@ export const spec = { contentType: 'application/json', withCredentials: true, }, - data: JSON.stringify(buildRequest(validBidRequests, bidderRequest)), + data: JSON.stringify(ortbRequest), bidderRequest, }); } @@ -673,11 +745,22 @@ export const spec = { interpretResponse: function (serverResponse, request) { const bidderRequest = request.bidderRequest; const body = serverResponse.body; - if (!body || body.id !== bidderRequest.bidderRequestId) { - logError('insticator: response id does not match bidderRequestId'); + + // Handle 204 No Content or empty response body (valid "no bid" scenario) + if (!body || !body.id) { return []; } + // Validate response ID matches request ID + if (body.id !== bidderRequest.bidderRequestId) { + logError('insticator: response id does not match bidderRequestId', { + responseId: body.id, + bidderRequestId: bidderRequest.bidderRequestId + }); + return []; + } + + // No seatbid means no bids (valid scenario) if (!body.seatbid) { return []; } @@ -686,7 +769,9 @@ export const spec = { buildBidSet(seatbid, bidderRequest) ); - return bidsets.reduce((a, b) => a.concat(b), []); + const finalBids = bidsets.reduce((a, b) => a.concat(b), []); + + return finalBids; }, getUserSyncs: function (options, responses) { diff --git a/modules/instreamTracking.js b/modules/instreamTracking.js index 909c21b29bd..b63bb860d23 100644 --- a/modules/instreamTracking.js +++ b/modules/instreamTracking.js @@ -48,7 +48,7 @@ const whitelistedResources = /video|fetch|xmlhttprequest|other/; * * @return {boolean} returns TRUE if tracking started */ -export function trackInstreamDeliveredImpressions({adUnits, bidsReceived, bidderRequests}) { +export function trackInstreamDeliveredImpressions({ adUnits, bidsReceived, bidderRequests }) { const instreamTrackingConfig = config.getConfig('instreamTracking') || {}; // check if instreamTracking is enabled and performance api is available if (!instreamTrackingConfig.enabled || !window.performance || !window.performance.getEntriesByType) { @@ -74,7 +74,7 @@ export function trackInstreamDeliveredImpressions({adUnits, bidsReceived, bidder const instreamAdUnitsCount = Object.keys(instreamAdUnitMap).length; const start = Date.now(); - const {maxWindow, pollingFreq, urlPattern} = instreamTrackingConfig; + const { maxWindow, pollingFreq, urlPattern } = instreamTrackingConfig; let instreamWinningBidsCount = 0; let lastRead = 0; // offset for performance.getEntriesByType diff --git a/modules/insuradsBidAdapter.md b/modules/insuradsBidAdapter.md new file mode 100644 index 00000000000..11c0bc248e7 --- /dev/null +++ b/modules/insuradsBidAdapter.md @@ -0,0 +1,55 @@ +# Overview + +``` +Module Name: InsurAds Bid Adapter +Module Type: Bidder Adapter +Maintainer: jclimaco@insurads.com +``` + +# Description + +Connects to InsurAds network for bids. + +# Test Parameters + +## Web + +### Display +``` +var adUnits = [ + // Banner adUnit + { + code: 'banner-div', + mediaTypes: { + banner: { + sizes: [[300, 250], [300,600]] + } + }, + bids: [{ + bidder: 'insurads', + params: { + tagId: 'ToBeSupplied' + } + }] + }, +]; +``` + +### Video Instream +``` + var videoAdUnit = { + code: 'video1', + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream' + } + }, + bids: [{ + bidder: 'insurads', + params: { + tagId: 'ToBeSupplied' + } + }] + }; +``` diff --git a/modules/insuradsBidAdapter.ts b/modules/insuradsBidAdapter.ts new file mode 100644 index 00000000000..30f506118b7 --- /dev/null +++ b/modules/insuradsBidAdapter.ts @@ -0,0 +1,149 @@ +import { deepSetValue, generateUUID, logError } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { AdapterRequest, BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' + +import { interpretResponse, enrichImp, enrichRequest, getAmxId, getLocalStorageFunctionGenerator, getUserSyncs } from '../libraries/nexx360Utils/index.js'; +import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; +import { BidRequest, ClientBidderRequest } from '../src/adapterManager.js'; +import { ORTBImp, ORTBRequest } from '../src/prebid.public.js'; +import { config } from '../src/config.js'; + +const BIDDER_CODE = 'insurads'; +const REQUEST_URL = 'https://fast.nexx360.io/booster'; +const PAGE_VIEW_ID = generateUUID(); +const BIDDER_VERSION = '7.1'; +const GVLID = 596; +const ALT_KEY = 'nexx360_storage'; + +const DEFAULT_GZIP_ENABLED = false; + +type RequireAtLeastOne = + Omit & { + [K in Keys]-?: Required> & + Partial>> + }[Keys]; + +type InsurAdsBidParams = RequireAtLeastOne<{ + tagId?: string; + placement?: string; + videoTagId?: string; + nativeTagId?: string; + adUnitPath?: string; + adUnitName?: string; + divId?: string; + allBids?: boolean; + customId?: string; + bidders?: Record; +}, "tagId" | "placement">; + +declare module '../src/adUnits' { + interface BidderParams { + ['nexx360']: InsurAdsBidParams; + } +} + +export const STORAGE = getStorageManager({ + bidderCode: BIDDER_CODE, +}); + +export const getInsurAdsLocalStorage = getLocalStorageFunctionGenerator<{ nexx360Id: string }>( + STORAGE, + BIDDER_CODE, + ALT_KEY, + 'nexx360Id' +); + +export const getGzipSetting = (): boolean => { + const bidderConfig = config.getBidderConfig(); + const gzipEnabled = bidderConfig.insurads?.gzipEnabled; + + if (gzipEnabled === true || gzipEnabled === 'true') { + return true; + } + return DEFAULT_GZIP_ENABLED; +} + +const converter = ortbConverter({ + context: { + netRevenue: true, // or false if your adapter should set bidResponse.netRevenue = false + ttl: 90, // default bidResponse.ttl (when not specified in ORTB response.seatbid[].bid[].exp) + }, + imp(buildImp, bidRequest: BidRequest, context) { + let imp: ORTBImp = buildImp(bidRequest, context); + imp = enrichImp(imp, bidRequest); + const divId = bidRequest.params.divId || bidRequest.adUnitCode; + const slotEl: HTMLElement | null = typeof divId === 'string' ? document.getElementById(divId) : null; + if (slotEl) { + const { width, height } = getBoundingClientRect(slotEl); + deepSetValue(imp, 'ext.dimensions.slotW', width); + deepSetValue(imp, 'ext.dimensions.slotH', height); + deepSetValue(imp, 'ext.dimensions.cssMaxW', slotEl.style?.maxWidth); + deepSetValue(imp, 'ext.dimensions.cssMaxH', slotEl.style?.maxHeight); + } + deepSetValue(imp, 'ext.nexx360', bidRequest.params); + deepSetValue(imp, 'ext.nexx360.divId', divId); + if (bidRequest.params.adUnitPath) deepSetValue(imp, 'ext.adUnitPath', bidRequest.params.adUnitPath); + if (bidRequest.params.adUnitName) deepSetValue(imp, 'ext.adUnitName', bidRequest.params.adUnitName); + return imp; + }, + request(buildRequest, imps, bidderRequest, context) { + let request: ORTBRequest = buildRequest(imps, bidderRequest, context); + const amxId = getAmxId(STORAGE, BIDDER_CODE); + request = enrichRequest(request, amxId, PAGE_VIEW_ID, BIDDER_VERSION); + return request; + }, +}); + +const isBidRequestValid = (bid: BidRequest): boolean => { + if (bid.params.adUnitName && (typeof bid.params.adUnitName !== 'string' || bid.params.adUnitName === '')) { + logError('bid.params.adUnitName needs to be a string'); + return false; + } + if (bid.params.adUnitPath && (typeof bid.params.adUnitPath !== 'string' || bid.params.adUnitPath === '')) { + logError('bid.params.adUnitPath needs to be a string'); + return false; + } + if (bid.params.divId && (typeof bid.params.divId !== 'string' || bid.params.divId === '')) { + logError('bid.params.divId needs to be a string'); + return false; + } + if (bid.params.allBids && typeof bid.params.allBids !== 'boolean') { + logError('bid.params.allBids needs to be a boolean'); + return false; + } + if (!bid.params.tagId && !bid.params.videoTagId && !bid.params.nativeTagId && !bid.params.placement) { + logError('bid.params.tagId or bid.params.videoTagId or bid.params.nativeTagId or bid.params.placement must be defined'); + return false; + } + return true; +}; + +const buildRequests = ( + bidRequests: BidRequest[], + bidderRequest: ClientBidderRequest, +): AdapterRequest => { + const data: ORTBRequest = converter.toORTB({ bidRequests, bidderRequest }) + const adapterRequest: AdapterRequest = { + method: 'POST', + url: REQUEST_URL, + data, + options: { + endpointCompression: getGzipSetting() + }, + } + return adapterRequest; +} + +export const spec: BidderSpec = { + code: BIDDER_CODE, + gvlid: GVLID, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs, +}; + +registerBidder(spec); diff --git a/modules/integr8BidAdapter.js b/modules/integr8BidAdapter.js index 4505bd98147..0f521cd94f7 100644 --- a/modules/integr8BidAdapter.js +++ b/modules/integr8BidAdapter.js @@ -17,7 +17,7 @@ const SIZE_SEPARATOR = ';'; const BISKO_ID = 'integr8Id'; const STORAGE_ID = 'bisko-sid'; const SEGMENTS = 'integr8Segments'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/interactiveOffersBidAdapter.js b/modules/interactiveOffersBidAdapter.js index b7104776190..a7bca0b8edb 100644 --- a/modules/interactiveOffersBidAdapter.js +++ b/modules/interactiveOffersBidAdapter.js @@ -1,6 +1,6 @@ -import {deepClone, isNumber, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { deepClone, isNumber, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'interactiveOffers'; const ENDPOINT = 'https://prebid.ioadx.com/bidRequest/?partnerId='; @@ -139,7 +139,7 @@ function parseRequestPrebidjsToOpenRTB(prebidRequest, bidderRequest) { imp.banner.w = adSize[0]; imp.banner.h = adSize[1]; } - imp.banner.format.push({w: adSize[0], h: adSize[1]}); + imp.banner.format.push({ w: adSize[0], h: adSize[1] }); }); } }); diff --git a/modules/intersectionRtdProvider.js b/modules/intersectionRtdProvider.js index e1ef87f48e2..b57fd919d16 100644 --- a/modules/intersectionRtdProvider.js +++ b/modules/intersectionRtdProvider.js @@ -1,7 +1,7 @@ -import {submodule} from '../src/hook.js'; -import {isFn, logError} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { submodule } from '../src/hook.js'; +import { isFn, logError } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js'; import '../src/adapterManager.js'; @@ -11,7 +11,7 @@ function getIntersectionData(requestBidsObject, onDone, providerConfig, userCons const placeholdersMap = {}; let done = false; if (!observerAvailable) return complete(); - const observer = new IntersectionObserver(observerCallback, {threshold: 0.5}); + const observer = new IntersectionObserver(observerCallback, { threshold: 0.5 }); const adUnitCodes = requestBidsObject.adUnitCodes || []; const auctionDelay = config.getConfig('realTimeData.auctionDelay') || 0; const waitForIt = providerConfig.waitForIt; diff --git a/modules/invamiaBidAdapter.js b/modules/invamiaBidAdapter.js index 7f9a40e1473..f9cffcd30dd 100644 --- a/modules/invamiaBidAdapter.js +++ b/modules/invamiaBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; import { buildBannerRequests, interpretBannerResponse } from '../libraries/biddoInvamiaUtils/index.js'; /** diff --git a/modules/invibesBidAdapter.js b/modules/invibesBidAdapter.js index 69bb7cae6eb..1f4e51967b8 100644 --- a/modules/invibesBidAdapter.js +++ b/modules/invibesBidAdapter.js @@ -1,6 +1,6 @@ -import {getWinDimensions, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getWinDimensions, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -22,7 +22,7 @@ const CONSTANTS = { DISABLE_USER_SYNC: true }; -export const storage = getStorageManager({bidderCode: CONSTANTS.BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: CONSTANTS.BIDDER_CODE }); export const spec = { code: CONSTANTS.BIDDER_CODE, @@ -225,7 +225,7 @@ function buildRequest(bidRequests, bidderRequest) { method: CONSTANTS.METHOD, url: endpoint, data: data, - options: {withCredentials: true}, + options: { withCredentials: true }, // for POST: { contentType: 'application/json', withCredentials: true } bidRequests: bidRequests }; diff --git a/modules/iqxBidAdapter.js b/modules/iqxBidAdapter.js index e859dfd2c01..49362a2e0ae 100644 --- a/modules/iqxBidAdapter.js +++ b/modules/iqxBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; const BIDDER_CODE = 'iqx'; const ENDPOINT = 'https://pbjs.iqzonertb.live'; diff --git a/modules/ivsBidAdapter.js b/modules/ivsBidAdapter.js index f6baedec2ee..bbe1ad4ede4 100644 --- a/modules/ivsBidAdapter.js +++ b/modules/ivsBidAdapter.js @@ -1,5 +1,5 @@ import { ortbConverter } from '../libraries/ortbConverter/converter.js'; -import {deepAccess, deepSetValue, getBidIdParameter, logError} from '../src/utils.js'; +import { deepAccess, deepSetValue, getBidIdParameter, logError } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO } from '../src/mediaTypes.js'; import { INSTREAM } from '../src/video.js'; @@ -64,7 +64,7 @@ export const spec = { * @return {Object} Info describing the request to the server. */ buildRequests: function(validBidRequests, bidderRequest) { - const data = converter.toORTB({ bidderRequest, validBidRequests, context: {mediaType: 'video'} }); + const data = converter.toORTB({ bidderRequest, validBidRequests, context: { mediaType: 'video' } }); deepSetValue(data.site, 'publisher.id', validBidRequests[0].params.publisherId); return { diff --git a/modules/ixBidAdapter.js b/modules/ixBidAdapter.js index 1df9570aab8..18413ad5d77 100644 --- a/modules/ixBidAdapter.js +++ b/modules/ixBidAdapter.js @@ -22,7 +22,7 @@ import { getStorageManager } from '../src/storageManager.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { INSTREAM, OUTSTREAM } from '../src/video.js'; import { Renderer } from '../src/Renderer.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; const divIdCache = {}; @@ -976,7 +976,8 @@ function addImpressions(impressions, impKeys, r, adUnitIndex) { banner: { topframe, format: bannerImps.map(({ banner: { w, h }, ext }) => ({ w, h, ext })) - }}; + } + }; for (let i = 0; i < _bannerImpression.banner.format.length; i++) { // We add sid and externalID in imp.ext therefore, remove from banner.format[].ext @@ -1172,7 +1173,7 @@ function addFPD(bidderRequest, r, fpd, site, user) { }); if (fpd.device) { - const sua = {...fpd.device.sua}; + const sua = { ...fpd.device.sua }; if (!isEmpty(sua)) { deepSetValue(r, 'device.sua', sua); } diff --git a/modules/jixieBidAdapter.js b/modules/jixieBidAdapter.js index 3a4df75762b..418fbeb7a63 100644 --- a/modules/jixieBidAdapter.js +++ b/modules/jixieBidAdapter.js @@ -1,18 +1,18 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {deepAccess, isArray, logWarn, isFn, isPlainObject, logError, logInfo, getWinDimensions} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {Renderer} from '../src/Renderer.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { deepAccess, isArray, logWarn, isFn, isPlainObject, logError, logInfo, getWinDimensions } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { Renderer } from '../src/Renderer.js'; const ADAPTER_VERSION = '2.1.0'; const PREBID_VERSION = '$prebid.version$'; const BIDDER_CODE = 'jixie'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const JX_OUTSTREAM_RENDERER_URL = 'https://scripts.jixie.media/jxhbrenderer.1.1.min.js'; const REQUESTS_URL = 'https://hb.jixie.io/v2/hbpost'; const sidTTLMins_ = 30; @@ -130,7 +130,7 @@ function createRenderer_(bidAd, scriptUrl, createFcn) { id: bidAd.adUnitCode, url: scriptUrl, loaded: false, - config: {'player_height': bidAd.height, 'player_width': bidAd.width}, + config: { 'player_height': bidAd.height, 'player_width': bidAd.width }, adUnitCode: bidAd.adUnitCode }); try { @@ -307,7 +307,7 @@ export const spec = { if (syncOptions.iframeEnabled) { syncs.push(sync.uf ? { url: sync.uf, type: 'iframe' } : { url: sync.up, type: 'image' }); } else if (syncOptions.pixelEnabled && sync.up) { - syncs.push({url: sync.up, type: 'image'}) + syncs.push({ url: sync.up, type: 'image' }) } }) return syncs; diff --git a/modules/justIdSystem.js b/modules/justIdSystem.js index 4ced4025ef6..eade64521e9 100644 --- a/modules/justIdSystem.js +++ b/modules/justIdSystem.js @@ -53,7 +53,7 @@ export const justIdSubmodule = { decode(value) { utils.logInfo(LOG_PREFIX, 'decode', value); const justId = value && value.uid; - return justId && {justId: justId}; + return justId && { justId: justId }; }, /** @@ -89,7 +89,7 @@ export const justIdSubmodule = { cbFun(); return; } - cbFun({uid: justId}); + cbFun({ uid: justId }); }, err => { utils.logError(LOG_PREFIX, 'error during fetching', err); cbFun(); diff --git a/modules/jwplayerBidAdapter.js b/modules/jwplayerBidAdapter.js index 9ee7312bb84..8a6b2909f60 100644 --- a/modules/jwplayerBidAdapter.js +++ b/modules/jwplayerBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO } from '../src/mediaTypes.js'; import { isArray, isFn, deepAccess, deepSetValue, logError, logWarn } from '../src/utils.js'; diff --git a/modules/jwplayerRtdProvider.js b/modules/jwplayerRtdProvider.js index 860d31688bf..48570d6d43d 100644 --- a/modules/jwplayerRtdProvider.js +++ b/modules/jwplayerRtdProvider.js @@ -9,11 +9,11 @@ * @requires module:modules/realTimeData */ -import {submodule} from '../src/hook.js'; -import {config} from '../src/config.js'; -import {ajaxBuilder} from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { config } from '../src/config.js'; +import { ajaxBuilder } from '../src/ajax.js'; import { deepAccess, logError, logWarn } from '../src/utils.js' -import {getGlobal} from '../src/prebidGlobal.js'; +import { getGlobal } from '../src/prebidGlobal.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -52,7 +52,7 @@ export const jwplayerSubmodule = { init }; -config.getConfig('realTimeData', ({realTimeData}) => { +config.getConfig('realTimeData', ({ realTimeData }) => { const providers = realTimeData.dataProviders; const jwplayerProvider = providers && ((providers) || []).find(pr => pr.name && pr.name.toLowerCase() === SUBMODULE_NAME); const params = jwplayerProvider && jwplayerProvider.params; diff --git a/modules/jwplayerVideoProvider.js b/modules/jwplayerVideoProvider.js index ee8bd15f9d6..6516b3d3cea 100644 --- a/modules/jwplayerVideoProvider.js +++ b/modules/jwplayerVideoProvider.js @@ -127,7 +127,7 @@ export function JWPlayerProvider(config, jwplayer_, adState_, timeState_, callba battr: adConfig.battr, maxextended: -1, // extension is allowed, and there is no time limit imposed. boxingallowed: 1, - playbackmethod: [ utils.getPlaybackMethod(config) ], + playbackmethod: [utils.getPlaybackMethod(config)], playbackend: 1, // TODO: need to account for floating player - https://developer.jwplayer.com/jwplayer/docs/jw8-embed-an-outstream-player , https://developer.jwplayer.com/jwplayer/docs/jw8-player-configuration-reference#section-float-on-scroll // companionad - TODO add in future version // companiontype - TODO add in future version diff --git a/modules/kargoBidAdapter.js b/modules/kargoBidAdapter.js index 1909112d36d..cba29908229 100644 --- a/modules/kargoBidAdapter.js +++ b/modules/kargoBidAdapter.js @@ -16,7 +16,7 @@ const BIDDER = Object.freeze({ SUPPORTED_MEDIA_TYPES: [BANNER, VIDEO], }); -const STORAGE = getStorageManager({bidderCode: BIDDER.CODE}); +const STORAGE = getStorageManager({ bidderCode: BIDDER.CODE }); const CURRENCY = Object.freeze({ KEY: 'currency', diff --git a/modules/kimberliteBidAdapter.js b/modules/kimberliteBidAdapter.js index 637afe328da..f38696779a8 100644 --- a/modules/kimberliteBidAdapter.js +++ b/modules/kimberliteBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { deepSetValue, replaceMacros } from '../src/utils.js'; -import {ORTB_MTYPES} from '../libraries/ortbConverter/processors/mediaType.js'; +import { ORTB_MTYPES } from '../libraries/ortbConverter/processors/mediaType.js'; const VERSION = '1.1.0'; @@ -86,7 +86,7 @@ export const spec = { }, interpretResponse(serverResponse, bidRequest) { - const bids = converter.fromORTB({response: serverResponse.body, request: bidRequest.data}).bids; + const bids = converter.fromORTB({ response: serverResponse.body, request: bidRequest.data }).bids; return bids; } }; @@ -96,7 +96,7 @@ export function expandAuctionMacros(str, price, currency) { const defaultCurrency = 'RUB'; - return replaceMacros(str, {AUCTION_PRICE: price, AUCTION_CURRENCY: currency || defaultCurrency}); + return replaceMacros(str, { AUCTION_PRICE: price, AUCTION_CURRENCY: currency || defaultCurrency }); }; registerBidder(spec); diff --git a/modules/kinessoIdSystem.js b/modules/kinessoIdSystem.js index 1a86c07ebba..8653a7a6737 100644 --- a/modules/kinessoIdSystem.js +++ b/modules/kinessoIdSystem.js @@ -6,8 +6,8 @@ */ import { logError, logInfo } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -182,7 +182,7 @@ function encodeId(value) { * @return {string} */ function kinessoSyncUrl(accountId, consentData) { - const {gdpr, usp: usPrivacyString} = consentData ?? {}; + const { gdpr, usp: usPrivacyString } = consentData ?? {}; let kinessoSyncUrl = `${ID_SVC}?accountid=${accountId}`; if (usPrivacyString) { kinessoSyncUrl = `${kinessoSyncUrl}&us_privacy=${usPrivacyString}`; @@ -235,8 +235,8 @@ export const kinessoIdSubmodule = { const kinessoIdPayload = {}; kinessoIdPayload.id = knnsoId; const payloadString = JSON.stringify(kinessoIdPayload); - ajax(kinessoSyncUrl(accountId, consentData), syncId(knnsoId), payloadString, {method: 'POST', withCredentials: true}); - return {'id': knnsoId}; + ajax(kinessoSyncUrl(accountId, consentData), syncId(knnsoId), payloadString, { method: 'POST', withCredentials: true }); + return { 'id': knnsoId }; }, eids: { 'kpuid': { diff --git a/modules/koblerBidAdapter.js b/modules/koblerBidAdapter.js index 2b0c55b2fb9..a4b83df1359 100644 --- a/modules/koblerBidAdapter.js +++ b/modules/koblerBidAdapter.js @@ -7,9 +7,9 @@ import { replaceAuctionPrice, triggerPixel } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const additionalData = new WeakMap(); @@ -204,7 +204,12 @@ function buildOpenRtbImpObject(validBidRequest) { }, bidfloor: floorInfo.floor, bidfloorcur: floorInfo.currency, - pmp: buildPmpObject(validBidRequest) + pmp: buildPmpObject(validBidRequest), + ext: { + prebid: { + adunitcode: validBidRequest.adUnitCode + } + } }; } diff --git a/modules/kubientBidAdapter.js b/modules/kubientBidAdapter.js index 425dbbcf4b9..9a8a1253c31 100644 --- a/modules/kubientBidAdapter.js +++ b/modules/kubientBidAdapter.js @@ -1,6 +1,6 @@ import { isArray, deepAccess, isPlainObject } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { config } from '../src/config.js'; const BIDDER_CODE = 'kubient'; @@ -9,7 +9,7 @@ const VERSION = '1.1'; const VENDOR_ID = 794; export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: function (bid) { return !!( bid && @@ -31,7 +31,7 @@ export const spec = { if (typeof bid.getFloor === 'function') { const mediaType = (Object.keys(bid.mediaTypes).length === 1) ? Object.keys(bid.mediaTypes)[0] : '*'; const sizes = bid.sizes || '*'; - const floorInfo = bid.getFloor({currency: 'USD', mediaType: mediaType, size: sizes}); + const floorInfo = bid.getFloor({ currency: 'USD', mediaType: mediaType, size: sizes }); if (isPlainObject(floorInfo) && floorInfo.currency === 'USD') { const floor = parseFloat(floorInfo.floor) if (!isNaN(floor) && floor > 0) { diff --git a/modules/kueezRtbBidAdapter.js b/modules/kueezRtbBidAdapter.js index 60eced6a490..aa42e11455e 100644 --- a/modules/kueezRtbBidAdapter.js +++ b/modules/kueezRtbBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { createBuildRequestsFn, createInterpretResponseFn, @@ -13,7 +13,7 @@ const GVLID = 1165; const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'kueezrtb'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -62,7 +62,7 @@ function getFirstPartyUUID() { }; function createUniqueRequestData(hashUrl, bid) { - const {auctionId, transactionId} = bid; + const { auctionId, transactionId } = bid; const fdata = getAndSetFirstPartyData(); return { auctionId, diff --git a/modules/lassoBidAdapter.js b/modules/lassoBidAdapter.js index 16e714823a4..1a4e97fb19b 100644 --- a/modules/lassoBidAdapter.js +++ b/modules/lassoBidAdapter.js @@ -9,7 +9,7 @@ const BIDDER_CODE = 'lasso'; const ENDPOINT_URL = 'https://trc.lhmos.com/prebid'; const GET_IUD_URL = 'https://secure.adnxs.com/getuid?'; const COOKIE_NAME = 'aim-xr'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/leagueMBidAdapter.js b/modules/leagueMBidAdapter.js new file mode 100644 index 00000000000..9171ee50705 --- /dev/null +++ b/modules/leagueMBidAdapter.js @@ -0,0 +1,17 @@ +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'leagueM'; +const ENDPOINT = 'https://pbjs.league-m.media'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + isBidRequestValid: bid => isBidRequestValid(bid, ['pid']), + buildRequests: (validBidRequests, bidderRequest) => buildRequests(validBidRequests, bidderRequest, ENDPOINT), + interpretResponse, + getUserSyncs +} + +registerBidder(spec); diff --git a/modules/leagueMBidAdapter.md b/modules/leagueMBidAdapter.md new file mode 100644 index 00000000000..5ef96b0d66b --- /dev/null +++ b/modules/leagueMBidAdapter.md @@ -0,0 +1,54 @@ +# Overview + +``` +Module Name: LeagueM Bidder Adapter +Module Type: LeagueM Bidder Adapter +Maintainer: prebid@league-m.com +``` + +# Description + +Module that connects to league-m.media demand sources + +# Test Parameters +``` +var adUnits = [ + { + code: 'test-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]], + } + }, + bids: [ + { + bidder: 'leagueM', + params: { + env: 'leagueM', + pid: 'aa8217e20131c095fe9dba67981040b0', + ext: {} + } + } + ] + }, + { + code: 'test-video', + sizes: [ [ 640, 480 ] ], + mediaTypes: { + video: { + playerSize: [640, 480], + context: 'instream', + skippable: true + } + }, + bids: [{ + bidder: 'leagueM', + params: { + env: 'leagueM', + pid: 'aa8217e20131c095fe9dba67981040b0', + ext: {} + } + }] + } +]; +``` diff --git a/modules/lifestreetBidAdapter.js b/modules/lifestreetBidAdapter.js index 16e17ac50b3..b6db322804a 100644 --- a/modules/lifestreetBidAdapter.js +++ b/modules/lifestreetBidAdapter.js @@ -39,8 +39,8 @@ function template(strings, ...keys) { * @param {BidRequest} bid The bid params to use for formatting a request */ function formatBidRequest(bid, bidderRequest = {}) { - const {params} = bid; - const {referer} = (bidderRequest.refererInfo || {}); + const { params } = bid; + const { referer } = (bidderRequest.refererInfo || {}); let url = urlTemplate({ adapter: 'prebid', slot: params.slot, @@ -90,7 +90,7 @@ export const spec = { supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid: (bid = {}) => { - const {params = {}} = bid; + const { params = {} } = bid; return !!(params.slot && params.adkey && params.ad_size); }, diff --git a/modules/limelightDigitalBidAdapter.js b/modules/limelightDigitalBidAdapter.js index 283a89c5a3f..102aca146bf 100644 --- a/modules/limelightDigitalBidAdapter.js +++ b/modules/limelightDigitalBidAdapter.js @@ -1,7 +1,8 @@ -import { logMessage, groupBy, flatten, uniques } from '../src/utils.js'; +import { uniques, flatten, deepSetValue } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { ajax } from '../src/ajax.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -10,6 +11,9 @@ import { ajax } from '../src/ajax.js'; */ const BIDDER_CODE = 'limelightDigital'; +const DEFAULT_NET_REVENUE = true; +const DEFAULT_TTL = 300; +const MTYPE_MAP = { 1: BANNER, 2: VIDEO }; /** * Determines whether or not the given bid response is valid. @@ -21,7 +25,7 @@ function isBidResponseValid(bid) { if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency || !bid.meta.advertiserDomains) { return false; } - switch (bid.meta.mediaType) { + switch (bid.mediaType) { case BANNER: return Boolean(bid.width && bid.height && bid.ad); case VIDEO: @@ -30,12 +34,46 @@ function isBidResponseValid(bid) { return false; } +const converter = ortbConverter({ + context: { + netRevenue: DEFAULT_NET_REVENUE, + ttl: DEFAULT_TTL + }, + imp(buildImp, bidRequest, context) { + const imp = buildImp(bidRequest, context); + for (let i = 1; i <= 5; i++) { + const customValue = bidRequest.params[`custom${i}`]; + if (customValue !== undefined) { + deepSetValue(imp, `ext.c${i}`, customValue); + } + } + deepSetValue(imp, `ext.adUnitId`, bidRequest.params.adUnitId); + return imp; + }, + bidResponse(buildBidResponse, bid, context) { + let mediaType; + if (bid.mtype) { + mediaType = MTYPE_MAP[bid.mtype]; + } + if (!mediaType && bid.ext?.mediaType) { + mediaType = bid.ext.mediaType; + } + if (!mediaType && context.imp) { + if (context.imp.banner) mediaType = BANNER; + else if (context.imp.video) mediaType = VIDEO; + } + if (mediaType) { + context.mediaType = mediaType; + } + return buildBidResponse(bid, context); + } +}); + export const spec = { code: BIDDER_CODE, aliases: [ { code: 'pll' }, { code: 'iionads', gvlid: 1358 }, - { code: 'apester' }, { code: 'adsyield' }, { code: 'tgm' }, { code: 'adtg_org' }, @@ -45,12 +83,12 @@ export const spec = { { code: 'stellorMediaRtb' }, { code: 'smootai' }, { code: 'anzuExchange' }, - { code: 'adnimation' }, { code: 'rtbdemand' }, { code: 'altstar' }, { code: 'vaayaMedia' }, { code: 'performist' }, - { code: 'oveeo' } + { code: 'oveeo' }, + { code: 'embimedia' } ], supportedMediaTypes: [BANNER, VIDEO], @@ -66,22 +104,62 @@ export const spec = { }, /** - * Make a server request from the list of BidRequests. + * Make a server request from the list of BidRequests using OpenRTB format. * - * @return ServerRequest Info describing the request to the server. + * @param {BidRequest[]} validBidRequests - Array of valid bid requests + * @param {Object} bidderRequest - The bidder request object + * @return {Object[]} Array of server requests */ buildRequests: (validBidRequests, bidderRequest) => { - let winTop; - try { - winTop = window.top; - winTop.location.toString(); - } catch (e) { - logMessage(e); - winTop = window; - } - const placements = groupBy(validBidRequests.map(bidRequest => buildPlacement(bidRequest)), 'host') - return Object.keys(placements) - .map(host => buildRequest(winTop, host, placements[host].map(placement => placement.adUnit), bidderRequest)); + const normalizedBids = validBidRequests.map(bid => { + const adUnitType = bid.params.adUnitType || BANNER + if (!bid.mediaTypes && bid.sizes) { + if (adUnitType === BANNER) { + return { ...bid, mediaTypes: { banner: { sizes: bid.sizes } } }; + } else { + return { ...bid, mediaTypes: { video: { playerSize: bid.sizes } } }; + } + } + if (bid.mediaTypes && bid.sizes) { + const mediaTypes = { ...bid.mediaTypes }; + if (adUnitType === BANNER && mediaTypes.banner) { + mediaTypes.banner = { + ...mediaTypes.banner, + sizes: (mediaTypes.banner.sizes || []).concat(bid.sizes) + }; + } + if (adUnitType === VIDEO && mediaTypes.video) { + mediaTypes.video = { + ...mediaTypes.video, + playerSize: (mediaTypes.video.playerSize || []).concat(bid.sizes) + }; + } + return { ...bid, mediaTypes }; + } + return bid; + }); + const bidRequestsByHost = normalizedBids.reduce((groups, bid) => { + const host = bid.params.host; + groups[host] = groups[host] || []; + groups[host].push(bid); + return groups; + }, {}); + const enrichedBidderRequest = { + ...bidderRequest, + ortb2: { + ...bidderRequest.ortb2, + site: { + ...bidderRequest.ortb2?.site, + page: bidderRequest.ortb2?.site?.page || bidderRequest.refererInfo?.page + } + } + }; + + return Object.entries(bidRequestsByHost).map(([host, bids]) => ({ + method: 'POST', + url: `https://${host}/ortbhb`, + data: converter.toORTB({ bidRequests: bids, bidderRequest: enrichedBidderRequest }) + })); }, /** @@ -100,22 +178,20 @@ export const spec = { }, /** - * Unpack the response from the server into a list of bids. + * Unpack the OpenRTB response from the server into a list of bids. * - * @param {ServerResponse} serverResponse A successful response from the server. - * @return {Bid[]} An array of bids which were nested inside the server. + * @param {ServerResponse} response - A successful response from the server + * @param {Object} request - The request object that was sent + * @return {Bid[]} An array of bids */ - interpretResponse: (serverResponse, bidRequest) => { - const bidResponses = []; - const serverBody = serverResponse.body; - const len = serverBody.length; - for (let i = 0; i < len; i++) { - const bidResponse = serverBody[i]; - if (isBidResponseValid(bidResponse)) { - bidResponses.push(bidResponse); - } + interpretResponse: (response, request) => { + if (!response.body) { + return []; } - return bidResponses; + return converter.fromORTB({ + response: response.body, + request: request.data + }).bids.filter(bid => isBidResponseValid(bid)); }, getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => { @@ -137,74 +213,3 @@ export const spec = { }; registerBidder(spec); - -function buildRequest(winTop, host, adUnits, bidderRequest) { - return { - method: 'POST', - url: `https://${host}/hb`, - data: { - secure: (location.protocol === 'https:'), - deviceWidth: winTop.screen.width, - deviceHeight: winTop.screen.height, - adUnits: adUnits, - ortb2: bidderRequest?.ortb2, - refererInfo: bidderRequest?.refererInfo, - sua: bidderRequest?.ortb2?.device?.sua, - page: bidderRequest?.ortb2?.site?.page || bidderRequest?.refererInfo?.page - } - } -} - -function buildPlacement(bidRequest) { - let sizes; - if (bidRequest.mediaTypes) { - switch (bidRequest.params.adUnitType) { - case BANNER: - if (bidRequest.mediaTypes.banner && bidRequest.mediaTypes.banner.sizes) { - sizes = bidRequest.mediaTypes.banner.sizes; - } - break; - case VIDEO: - if (bidRequest.mediaTypes.video && bidRequest.mediaTypes.video.playerSize) { - sizes = [bidRequest.mediaTypes.video.playerSize]; - } - break; - } - } - sizes = (sizes || []).concat(bidRequest.sizes || []); - return { - host: bidRequest.params.host, - adUnit: { - id: bidRequest.params.adUnitId, - bidId: bidRequest.bidId, - transactionId: bidRequest.ortb2Imp?.ext?.tid, - sizes: sizes.map(size => { - let floorInfo = null; - if (typeof bidRequest.getFloor === 'function') { - try { - floorInfo = bidRequest.getFloor({ - currency: 'USD', - mediaType: bidRequest.params.adUnitType, - size: [size[0], size[1]] - }); - } catch (e) {} - } - return { - width: size[0], - height: size[1], - floorInfo: floorInfo - }; - }), - type: bidRequest.params.adUnitType.toUpperCase(), - ortb2Imp: bidRequest.ortb2Imp, - publisherId: bidRequest.params.publisherId, - userIdAsEids: bidRequest.userIdAsEids, - supplyChain: bidRequest?.ortb2?.source?.ext?.schain, - custom1: bidRequest.params.custom1, - custom2: bidRequest.params.custom2, - custom3: bidRequest.params.custom3, - custom4: bidRequest.params.custom4, - custom5: bidRequest.params.custom5 - } - } -} diff --git a/modules/liveIntentAnalyticsAdapter.js b/modules/liveIntentAnalyticsAdapter.js index 1a548bfcd9c..6733f441159 100644 --- a/modules/liveIntentAnalyticsAdapter.js +++ b/modules/liveIntentAnalyticsAdapter.js @@ -7,7 +7,7 @@ import { getRefererInfo } from '../src/refererDetection.js'; import { config as prebidConfig } from '../src/config.js'; import { auctionManager } from '../src/auctionManager.js'; -import {getGlobalVarName} from '../src/buildOptions.js'; +import { getGlobalVarName } from '../src/buildOptions.js'; const ANALYTICS_TYPE = 'endpoint'; const URL = 'https://wba.liadm.com/analytic-events'; @@ -19,7 +19,7 @@ const INTEGRATION_ID = getGlobalVarName(); let partnerIdFromUserIdConfig; let sendAuctionInitEvents; -const liAnalytics = Object.assign(adapter({URL, ANALYTICS_TYPE}), { +const liAnalytics = Object.assign(adapter({ URL, ANALYTICS_TYPE }), { track({ eventType, args }) { switch (eventType) { case AUCTION_INIT: @@ -66,7 +66,7 @@ function handleAuctionInitEvent(auctionInitEvent) { } function handleBidWonEvent(bidWonEvent) { - const auction = auctionManager.index.getAuction({auctionId: bidWonEvent.auctionId}); + const auction = auctionManager.index.getAuction({ auctionId: bidWonEvent.auctionId }); const liveIntentIdsPresent = checkLiveIntentIdsPresent(auction?.getBidRequests()) // This is for old integration that enable or disable the user id module diff --git a/modules/liveIntentRtdProvider.js b/modules/liveIntentRtdProvider.js index 92cd09ae346..affe336d1ca 100644 --- a/modules/liveIntentRtdProvider.js +++ b/modules/liveIntentRtdProvider.js @@ -2,7 +2,7 @@ * This module adds the LiveIntent provider to the Real Time Data module (rtdModule). */ import { submodule } from '../src/hook.js'; -import {deepAccess, deepSetValue} from '../src/utils.js' +import { deepAccess, deepSetValue } from '../src/utils.js' /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule diff --git a/modules/livewrappedAnalyticsAdapter.js b/modules/livewrappedAnalyticsAdapter.js index 37b73368fdc..abeb2095ff7 100644 --- a/modules/livewrappedAnalyticsAdapter.js +++ b/modules/livewrappedAnalyticsAdapter.js @@ -1,5 +1,5 @@ import { timestamp, logInfo } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; @@ -23,15 +23,15 @@ const cache = { auctions: {} }; -const livewrappedAnalyticsAdapter = Object.assign(adapter({EMPTYURL, ANALYTICSTYPE}), { - track({eventType, args}) { +const livewrappedAnalyticsAdapter = Object.assign(adapter({ EMPTYURL, ANALYTICSTYPE }), { + track({ eventType, args }) { const time = timestamp(); logInfo('LIVEWRAPPED_EVENT:', [eventType, args]); switch (eventType) { case EVENTS.AUCTION_INIT: logInfo('LIVEWRAPPED_AUCTION_INIT:', args); - cache.auctions[args.auctionId] = {bids: {}, bidAdUnits: {}}; + cache.auctions[args.auctionId] = { bids: {}, bidAdUnits: {} }; break; case EVENTS.BID_REQUESTED: logInfo('LIVEWRAPPED_BID_REQUESTED:', args); @@ -189,7 +189,7 @@ livewrappedAnalyticsAdapter.sendEvents = function() { return; } - ajax(initOptions.endpoint || URL, undefined, JSON.stringify(events), {method: 'POST'}); + ajax(initOptions.endpoint || URL, undefined, JSON.stringify(events), { method: 'POST' }); setTimeout(() => { sentRequests.auctionIds.forEach(id => { @@ -233,7 +233,7 @@ function getSentRequests() { }); }); - return {gdpr: gdpr, auctionIds: auctionIds, sentRequests: sentRequests}; + return { gdpr: gdpr, auctionIds: auctionIds, sentRequests: sentRequests }; } function getResponses(gdpr, auctionIds) { @@ -309,7 +309,7 @@ function getGdprPos(gdpr, auction) { } if (gdprPos === gdpr.length) { - gdpr[gdprPos] = {gdprApplies: auction.gdprApplies, gdprConsent: auction.gdprConsent}; + gdpr[gdprPos] = { gdprApplies: auction.gdprApplies, gdprConsent: auction.gdprConsent }; } return gdprPos; diff --git a/modules/livewrappedBidAdapter.js b/modules/livewrappedBidAdapter.js index 615c81fb098..922b0d46ef0 100644 --- a/modules/livewrappedBidAdapter.js +++ b/modules/livewrappedBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, getWindowTop, isSafariBrowser, mergeDeep, isFn, isPlainObject, getWinDimensions} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { deepAccess, getWindowTop, isSafariBrowser, mergeDeep, isFn, isPlainObject, getWinDimensions } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; /** @@ -11,7 +11,7 @@ import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.j */ const BIDDER_CODE = 'livewrapped'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const URL = 'https://lwadm.com/ad'; const VERSION = '1.4'; @@ -112,7 +112,8 @@ export const spec = { return { method: 'POST', url: bidUrl, - data: payloadString}; + data: payloadString + }; }, /** @@ -174,11 +175,11 @@ export const spec = { userSync.forEach(function(sync) { if (syncOptions.pixelEnabled && sync.type === 'Redirect') { - syncList.push({type: 'image', url: sync.url}); + syncList.push({ type: 'image', url: sync.url }); } if (syncOptions.iframeEnabled && sync.type === 'Iframe') { - syncList.push({type: 'iframe', url: sync.url}); + syncList.push({ type: 'iframe', url: sync.url }); } }); @@ -301,7 +302,7 @@ function getAdblockerRecovered() { function handleEids(bidRequests) { const bidRequest = bidRequests[0]; if (bidRequest && bidRequest.userIdAsEids) { - return {user: {ext: {eids: bidRequest.userIdAsEids}}}; + return { user: { ext: { eids: bidRequest.userIdAsEids } } }; } return undefined; diff --git a/modules/lm_kiviadsBidAdapter.js b/modules/lm_kiviadsBidAdapter.js index 7295eb33258..01eab4a86c3 100644 --- a/modules/lm_kiviadsBidAdapter.js +++ b/modules/lm_kiviadsBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; const BIDDER_CODE = 'lm_kiviads'; const ENDPOINT = 'https://pbjs.kiviads.live'; diff --git a/modules/locIdSystem.js b/modules/locIdSystem.js new file mode 100644 index 00000000000..5e06e29b302 --- /dev/null +++ b/modules/locIdSystem.js @@ -0,0 +1,676 @@ +/** + * This file is licensed under the Apache 2.0 license. + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +/** + * This module adds LocID to the User ID module + * The {@link module:modules/userId} module is required. + * @module modules/locIdSystem + * @requires module:modules/userId + */ + +import { logWarn, logError } from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { gppDataHandler, uspDataHandler } from '../src/adapterManager.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; + +const MODULE_NAME = 'locId'; +const LOG_PREFIX = 'LocID:'; +const DEFAULT_TIMEOUT_MS = 800; +const DEFAULT_EID_SOURCE = 'locid.com'; +// EID atype: 1 = AdCOM AgentTypeWeb (agent type for web environments) +const DEFAULT_EID_ATYPE = 1; +const MAX_ID_LENGTH = 512; +const MAX_CONNECTION_IP_LENGTH = 64; +const DEFAULT_IP_CACHE_TTL_MS = 4 * 60 * 60 * 1000; // 4 hours +const IP_CACHE_SUFFIX = '_ip'; + +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); + +/** + * Normalizes privacy mode config to a boolean flag. + * Supports both requirePrivacySignals (boolean) and privacyMode (string enum). + * + * Precedence: requirePrivacySignals (if true) takes priority over privacyMode. + * - privacyMode is the preferred high-level setting for new integrations. + * - requirePrivacySignals exists for backwards compatibility with integrators + * who prefer a simple boolean. + * + * @param {Object} params - config.params + * @returns {boolean} true if privacy signals are required, false otherwise + */ +function shouldRequirePrivacySignals(params) { + // requirePrivacySignals=true takes precedence (backwards compatibility) + if (params?.requirePrivacySignals === true) { + return true; + } + if (params?.privacyMode === 'requireSignals') { + return true; + } + // Default: allowWithoutSignals + return false; +} + +function getUspConsent(consentData) { + if (consentData && consentData.usp != null) { + return consentData.usp; + } + return consentData?.uspConsent; +} + +function getGppConsent(consentData) { + if (consentData && consentData.gpp != null) { + return consentData.gpp; + } + return consentData?.gppConsent; +} + +/** + * Checks if any privacy signals are present in consentData or data handlers. + * + * IMPORTANT: gdprApplies alone does NOT count as a privacy signal. + * A publisher may set gdprApplies=true without having a CMP installed. + * We only consider GDPR signals "present" when actual consent framework + * artifacts exist (consentString, vendorData). This supports LI-based + * operation where no TCF consent string is required. + * + * "Signals present" means ANY of the following are available: + * - consentString or gdpr.consentString (indicates CMP provided framework data) + * - vendorData or gdpr.vendorData (indicates CMP provided vendor data) + * - usp or uspConsent (US Privacy string) + * - gpp or gppConsent (GPP consent data) + * - Data from gppDataHandler or uspDataHandler + * + * @param {Object} consentData - The consent data object passed to getId + * @returns {boolean} true if any privacy signals are present + */ +function hasPrivacySignals(consentData) { + // Check GDPR-related signals (flat and nested) + // NOTE: gdprApplies alone is NOT a signal - it just indicates jurisdiction. + // A signal requires actual CMP artifacts (consentString or vendorData). + if (consentData?.consentString || consentData?.gdpr?.consentString) { + return true; + } + if (consentData?.vendorData || consentData?.gdpr?.vendorData) { + return true; + } + + // Check USP consent + const uspConsent = getUspConsent(consentData); + if (uspConsent) { + return true; + } + + // Check GPP consent + const gppConsent = getGppConsent(consentData); + if (gppConsent) { + return true; + } + + // Check data handlers + const uspFromHandler = uspDataHandler.getConsentData(); + if (uspFromHandler) { + return true; + } + + const gppFromHandler = gppDataHandler.getConsentData(); + if (gppFromHandler) { + return true; + } + + return false; +} + +function isValidId(id) { + return typeof id === 'string' && id.trim().length > 0 && id.length <= MAX_ID_LENGTH; +} + +function isValidConnectionIp(ip) { + return typeof ip === 'string' && ip.length > 0 && ip.length <= MAX_CONNECTION_IP_LENGTH; +} + +function normalizeStoredId(storedId) { + if (!storedId) { + return null; + } + if (typeof storedId === 'string') { + return null; + } + if (typeof storedId === 'object') { + // Preserve explicit null for id (means "empty tx_cloc, valid cached response"). + // 'id' in storedId is needed because ?? treats null as nullish and would + // incorrectly fall through to tx_cloc. + const hasExplicitId = 'id' in storedId; + const id = hasExplicitId ? storedId.id : (storedId.tx_cloc ?? null); + const connectionIp = storedId.connectionIp ?? storedId.connection_ip; + return { ...storedId, id, connectionIp }; + } + return null; +} + +/** + * Checks privacy framework signals. Returns true if ID operations are allowed. + * + * LocID operates under Legitimate Interest and does not require a TCF consent + * string when no privacy framework is present. When privacy signals exist, + * framework processing restrictions are enforced. + * + * @param {Object} consentData - The consent data object from Prebid + * @param {Object} params - config.params for privacy mode settings + * @returns {boolean} true if ID operations are allowed + */ +function hasValidConsent(consentData, params) { + const requireSignals = shouldRequirePrivacySignals(params); + const signalsPresent = hasPrivacySignals(consentData); + + // B) If privacy signals are NOT present + if (!signalsPresent) { + if (requireSignals) { + logWarn(LOG_PREFIX, 'Privacy signals required but none present'); + return false; + } + // Default: allow operation without privacy signals (LI-based operation) + return true; + } + + // A) Privacy signals ARE present - enforce applicable restrictions + // + // Note: privacy signals can come from GDPR, USP, or GPP. GDPR checks only + // apply when GDPR is flagged AND CMP artifacts (consentString/vendorData) + // are present. gdprApplies alone does not trigger GDPR enforcement. + + // Check GDPR - support both flat and nested shapes + const gdprApplies = consentData?.gdprApplies === true || consentData?.gdpr?.gdprApplies === true; + const consentString = consentData?.consentString || consentData?.gdpr?.consentString; + const vendorData = consentData?.vendorData || consentData?.gdpr?.vendorData; + const gdprCmpArtifactsPresent = !!(consentString || vendorData); + + if (gdprApplies && gdprCmpArtifactsPresent) { + // When GDPR applies AND we have CMP signals, require consentString + if (!consentString || consentString.length === 0) { + logWarn(LOG_PREFIX, 'GDPR framework data missing consent string'); + return false; + } + } + + // Check USP for processing restriction + const uspData = getUspConsent(consentData) ?? uspDataHandler.getConsentData(); + if (uspData && uspData.length >= 3 && uspData.charAt(2) === 'Y') { + logWarn(LOG_PREFIX, 'US Privacy framework processing restriction detected'); + return false; + } + + // Check GPP for processing restriction + const gppData = getGppConsent(consentData) ?? gppDataHandler.getConsentData(); + if (gppData?.applicableSections?.includes(7) && + gppData?.parsedSections?.usnat?.KnownChildSensitiveDataConsents?.includes(1)) { + logWarn(LOG_PREFIX, 'GPP usnat KnownChildSensitiveDataConsents processing restriction detected'); + return false; + } + + return true; +} + +function parseEndpointResponse(response) { + if (!response) { + return null; + } + try { + return typeof response === 'string' ? JSON.parse(response) : response; + } catch (e) { + logError(LOG_PREFIX, 'Error parsing endpoint response:', e.message); + return null; + } +} + +/** + * Extracts LocID from endpoint response. + * Only tx_cloc is accepted. + */ +function extractLocIdFromResponse(parsed) { + if (!parsed) return null; + + if (isValidId(parsed.tx_cloc)) { + return parsed.tx_cloc; + } + + logWarn(LOG_PREFIX, 'Could not extract valid tx_cloc from response'); + return null; +} + +function extractConnectionIp(parsed) { + if (!parsed) { + return null; + } + const connectionIp = parsed.connection_ip ?? parsed.connectionIp; + return isValidConnectionIp(connectionIp) ? connectionIp : null; +} + +function getIpCacheKey(config) { + const baseName = config?.storage?.name || '_locid'; + return config?.params?.ipCacheName || (baseName + IP_CACHE_SUFFIX); +} + +function getIpCacheTtlMs(config) { + const ttl = config?.params?.ipCacheTtlMs; + return (typeof ttl === 'number' && ttl > 0) ? ttl : DEFAULT_IP_CACHE_TTL_MS; +} + +function readIpCache(config) { + try { + const key = getIpCacheKey(config); + const raw = storage.getDataFromLocalStorage(key); + if (!raw) return null; + const entry = JSON.parse(raw); + if (!entry || typeof entry !== 'object') return null; + if (!isValidConnectionIp(entry.ip)) return null; + if (typeof entry.expiresAt === 'number' && Date.now() > entry.expiresAt) return null; + return entry; + } catch (e) { + logWarn(LOG_PREFIX, 'Error reading IP cache:', e.message); + return null; + } +} + +function writeIpCache(config, ip) { + if (!isValidConnectionIp(ip)) return; + try { + const key = getIpCacheKey(config); + const nowMs = Date.now(); + const ttlMs = getIpCacheTtlMs(config); + const entry = { + ip: ip, + fetchedAt: nowMs, + expiresAt: nowMs + ttlMs + }; + storage.setDataInLocalStorage(key, JSON.stringify(entry)); + } catch (e) { + logWarn(LOG_PREFIX, 'Error writing IP cache:', e.message); + } +} + +/** + * Parses an IP response from an IP-only endpoint. + * Supports JSON ({ip: "..."}, {connection_ip: "..."}) and plain text IP. + */ +function parseIpResponse(response) { + if (!response) return null; + + if (typeof response === 'string') { + const trimmed = response.trim(); + if (trimmed.charAt(0) === '{') { + try { + const parsed = JSON.parse(trimmed); + const ip = parsed.ip || parsed.connection_ip || parsed.connectionIp; + return isValidConnectionIp(ip) ? ip : null; + } catch (e) { + // Not valid JSON, try as plain text + } + } + return isValidConnectionIp(trimmed) ? trimmed : null; + } + + if (typeof response === 'object') { + const ip = response.ip || response.connection_ip || response.connectionIp; + return isValidConnectionIp(ip) ? ip : null; + } + + return null; +} + +/** + * Checks if a stored tx_cloc entry is valid for reuse. + * Accepts both valid id strings AND null (empty tx_cloc is a valid cached result). + */ +function isStoredEntryReusable(normalizedStored, currentIp) { + if (!normalizedStored || !isValidConnectionIp(normalizedStored.connectionIp)) { + return false; + } + if (isExpired(normalizedStored)) { + return false; + } + if (currentIp && normalizedStored.connectionIp !== currentIp) { + return false; + } + // id must be either a valid string or explicitly null (empty tx_cloc) + return normalizedStored.id === null || isValidId(normalizedStored.id); +} + +function getExpiresAt(config, nowMs) { + const expiresDays = config?.storage?.expires; + if (typeof expiresDays !== 'number' || expiresDays <= 0) { + return undefined; + } + return nowMs + (expiresDays * 24 * 60 * 60 * 1000); +} + +function buildStoredId(id, connectionIp, config) { + const nowMs = Date.now(); + return { + id, + connectionIp, + createdAt: nowMs, + updatedAt: nowMs, + expiresAt: getExpiresAt(config, nowMs) + }; +} + +function isExpired(storedEntry) { + return typeof storedEntry?.expiresAt === 'number' && Date.now() > storedEntry.expiresAt; +} + +/** + * Builds the request URL, appending altId if configured. + * Preserves URL fragments by appending query params before the hash. + */ +function buildRequestUrl(endpoint, altId) { + if (!altId) { + return endpoint; + } + + // Split on hash to preserve fragment + const hashIndex = endpoint.indexOf('#'); + let base = endpoint; + let fragment = ''; + + if (hashIndex !== -1) { + base = endpoint.substring(0, hashIndex); + fragment = endpoint.substring(hashIndex); + } + + const separator = base.includes('?') ? '&' : '?'; + return `${base}${separator}alt_id=${encodeURIComponent(altId)}${fragment}`; +} + +/** + * Fetches LocID from the configured endpoint (GET only). + */ +function fetchLocIdFromEndpoint(config, callback) { + const params = config?.params || {}; + const endpoint = params.endpoint; + const timeoutMs = params.timeoutMs || DEFAULT_TIMEOUT_MS; + + if (!endpoint) { + logError(LOG_PREFIX, 'No endpoint configured'); + callback(undefined); + return; + } + + const requestUrl = buildRequestUrl(endpoint, params.altId); + + const requestOptions = { + method: 'GET', + contentType: 'application/json', + withCredentials: params.withCredentials === true + }; + + // Add x-api-key header if apiKey is configured + if (params.apiKey) { + requestOptions.customHeaders = { + 'x-api-key': params.apiKey + }; + } + + let callbackFired = false; + const safeCallback = (result) => { + if (!callbackFired) { + callbackFired = true; + callback(result); + } + }; + + const onSuccess = (response) => { + const parsed = parseEndpointResponse(response); + if (!parsed) { + safeCallback(undefined); + return; + } + const connectionIp = extractConnectionIp(parsed); + if (!connectionIp) { + logWarn(LOG_PREFIX, 'Missing or invalid connection_ip in response'); + safeCallback(undefined); + return; + } + // tx_cloc may be null (empty/missing for this IP) -- this is a valid cacheable result. + // connection_ip is always required. + const locId = extractLocIdFromResponse(parsed); + writeIpCache(config, connectionIp); + safeCallback(buildStoredId(locId, connectionIp, config)); + }; + + const onError = (error) => { + logWarn(LOG_PREFIX, 'Request failed:', error); + safeCallback(undefined); + }; + + try { + const ajax = ajaxBuilder(timeoutMs); + ajax(requestUrl, { success: onSuccess, error: onError }, null, requestOptions); + } catch (e) { + logError(LOG_PREFIX, 'Error initiating request:', e.message); + safeCallback(undefined); + } +} + +/** + * Fetches the connection IP from a separate lightweight endpoint (GET only). + * Callback receives the IP string on success or null on failure. + */ +function fetchIpFromEndpoint(config, callback) { + const params = config?.params || {}; + const ipEndpoint = params.ipEndpoint; + const timeoutMs = params.timeoutMs || DEFAULT_TIMEOUT_MS; + + if (!ipEndpoint) { + callback(null); + return; + } + + let callbackFired = false; + const safeCallback = (result) => { + if (!callbackFired) { + callbackFired = true; + callback(result); + } + }; + + const onSuccess = (response) => { + const ip = parseIpResponse(response); + safeCallback(ip); + }; + + const onError = (error) => { + logWarn(LOG_PREFIX, 'IP endpoint request failed:', error); + safeCallback(null); + }; + + try { + const ajax = ajaxBuilder(timeoutMs); + const requestOptions = { + method: 'GET', + withCredentials: params.withCredentials === true + }; + if (params.apiKey) { + requestOptions.customHeaders = { + 'x-api-key': params.apiKey + }; + } + ajax(ipEndpoint, { success: onSuccess, error: onError }, null, requestOptions); + } catch (e) { + logError(LOG_PREFIX, 'Error initiating IP request:', e.message); + safeCallback(null); + } +} + +export const locIdSubmodule = { + name: MODULE_NAME, + aliasName: 'locid', + gvlid: VENDORLESS_GVLID, + + /** + * Decode stored value into userId object. + */ + decode(value) { + if (!value || typeof value !== 'object') { + return undefined; + } + const id = value?.id ?? value?.tx_cloc; + const connectionIp = value?.connectionIp ?? value?.connection_ip; + if (isValidId(id) && isValidConnectionIp(connectionIp)) { + return { locId: id }; + } + return undefined; + }, + + /** + * Get the LocID from endpoint. + * Returns {id} for sync or {callback} for async per Prebid patterns. + * + * Two-tier cache: IP cache (4h default) and tx_cloc cache (7d default). + * IP is refreshed more frequently to detect network changes while keeping + * tx_cloc stable for its full cache period. + */ + getId(config, consentData, storedId) { + const params = config?.params || {}; + + // Check privacy restrictions first + if (!hasValidConsent(consentData, params)) { + return undefined; + } + + const normalizedStored = normalizeStoredId(storedId); + const cachedIp = readIpCache(config); + + // Step 1: IP cache is valid -- check if tx_cloc matches + if (cachedIp) { + if (isStoredEntryReusable(normalizedStored, cachedIp.ip)) { + return { id: normalizedStored }; + } + // IP cached but tx_cloc missing, expired, or IP mismatch -- full fetch + return { + callback: (callback) => { + fetchLocIdFromEndpoint(config, callback); + } + }; + } + + // Step 2: IP cache expired or missing + if (params.ipEndpoint) { + // Two-call optimization: lightweight IP check first + return { + callback: (callback) => { + fetchIpFromEndpoint(config, (freshIp) => { + if (!freshIp) { + // IP fetch failed; fall back to main endpoint + fetchLocIdFromEndpoint(config, callback); + return; + } + writeIpCache(config, freshIp); + // Check if stored tx_cloc matches the fresh IP + if (isStoredEntryReusable(normalizedStored, freshIp)) { + callback(normalizedStored); + return; + } + // IP changed or no valid tx_cloc -- full fetch + fetchLocIdFromEndpoint(config, callback); + }); + } + }; + } + + // Step 3: No ipEndpoint configured -- call main endpoint to refresh IP. + // Only update tx_cloc if IP changed or tx_cloc cache expired. + return { + callback: (callback) => { + fetchLocIdFromEndpoint(config, (freshEntry) => { + if (!freshEntry) { + callback(undefined); + return; + } + // Honor empty tx_cloc: if the server returned null, use the fresh + // entry so stale identifiers are cleared (cached as id: null). + if (freshEntry.id === null) { + callback(freshEntry); + return; + } + // IP is already cached by fetchLocIdFromEndpoint's onSuccess. + // Check if we should preserve the existing tx_cloc (avoid churning it). + if (normalizedStored?.id !== null && isStoredEntryReusable(normalizedStored, freshEntry.connectionIp)) { + callback(normalizedStored); + return; + } + // IP changed or tx_cloc expired/missing -- use fresh entry + callback(freshEntry); + }); + } + }; + }, + + /** + * Extend existing LocID. + * Accepts id: null (empty tx_cloc) as a valid cached result. + * If IP cache is missing/expired/mismatched, return a callback to refresh. + */ + extendId(config, consentData, storedId) { + const normalizedStored = normalizeStoredId(storedId); + if (!normalizedStored || !isValidConnectionIp(normalizedStored.connectionIp)) { + return undefined; + } + // Accept both valid id strings AND null (empty tx_cloc is a valid cached result) + if (normalizedStored.id !== null && !isValidId(normalizedStored.id)) { + return undefined; + } + if (isExpired(normalizedStored)) { + return undefined; + } + if (!hasValidConsent(consentData, config?.params)) { + return undefined; + } + const refreshInSeconds = config?.storage?.refreshInSeconds; + if (typeof refreshInSeconds === 'number' && refreshInSeconds > 0) { + const createdAt = normalizedStored.createdAt; + if (typeof createdAt !== 'number') { + return undefined; + } + const refreshAfterMs = refreshInSeconds * 1000; + if (Date.now() - createdAt >= refreshAfterMs) { + return undefined; + } + } + // Check IP cache -- if expired/missing or IP changed, trigger re-fetch + const cachedIp = readIpCache(config); + if (!cachedIp || cachedIp.ip !== normalizedStored.connectionIp) { + return { + callback: (callback) => { + fetchLocIdFromEndpoint(config, callback); + } + }; + } + return { id: normalizedStored }; + }, + + /** + * EID configuration following standard Prebid shape. + */ + eids: { + locId: { + source: DEFAULT_EID_SOURCE, + atype: DEFAULT_EID_ATYPE, + getValue: function (data) { + if (typeof data === 'string') { + return data; + } + if (!data || typeof data !== 'object') { + return undefined; + } + return data?.id ?? data?.tx_cloc ?? data?.locId ?? data?.locid; + } + } + } +}; + +submodule('userId', locIdSubmodule); diff --git a/modules/locIdSystem.md b/modules/locIdSystem.md new file mode 100644 index 00000000000..6ffe02fe841 --- /dev/null +++ b/modules/locIdSystem.md @@ -0,0 +1,250 @@ +# LocID User ID Submodule + +## Overview + +The LocID User ID submodule retrieves a LocID from a configured first-party endpoint, honors applicable privacy framework processing restrictions when present, persists the identifier using Prebid's storage framework, and exposes the ID to bidders via the standard EIDs interface. + +LocID is a geospatial identifier provided by Digital Envoy. The endpoint is a publisher-controlled, first-party or on-premises service operated by the publisher, GrowthCode, or Digital Envoy. The endpoint derives location information server-side. The browser module does not transmit IP addresses. + +## Configuration + +```javascript +pbjs.setConfig({ + userSync: { + userIds: [{ + name: 'locId', + params: { + endpoint: 'https://id.example.com/locid', + ipEndpoint: 'https://id.example.com/ip' // optional: lightweight IP-only check + }, + storage: { + type: 'html5', + name: '_locid', + expires: 7 + } + }] + } +}); +``` + +## Parameters + +| Parameter | Type | Required | Default | Description | +| ----------------------- | ------- | -------- | ----------------------- | ----------------------------------------------------------------------------- | +| `endpoint` | String | Yes | – | First-party LocID endpoint (see Endpoint Requirements below) | +| `ipEndpoint` | String | No | – | Separate endpoint returning the connection IP (see IP Change Detection below) | +| `ipCacheTtlMs` | Number | No | `14400000` (4h) | TTL for the IP cache entry in milliseconds | +| `ipCacheName` | String | No | `{storage.name}_ip` | localStorage key for the IP cache (auto-derived if not set) | +| `altId` | String | No | – | Alternative identifier appended as `?alt_id=` query param | +| `timeoutMs` | Number | No | `800` | Request timeout in milliseconds | +| `withCredentials` | Boolean | No | `false` | Whether to include credentials on the request | +| `apiKey` | String | No | – | API key sent as `x-api-key` header on `endpoint` and `ipEndpoint` requests | +| `requirePrivacySignals` | Boolean | No | `false` | If `true`, requires privacy signals to be present | +| `privacyMode` | String | No | `'allowWithoutSignals'` | `'allowWithoutSignals'` or `'requireSignals'` | + +**Note on privacy configuration:** `privacyMode` is the preferred high-level setting for new integrations. `requirePrivacySignals` exists for backwards compatibility with integrators who prefer a simple boolean. If `requirePrivacySignals: true` is set, it takes precedence. + +### Endpoint Requirements + +The `endpoint` parameter must point to a **first-party proxy** or **on-premises service**—not the raw LocID Encrypt API directly. + +The LocID Encrypt API (`GET /encrypt?ip=&alt_id=`) requires the client IP address as a parameter. Since browsers cannot reliably determine their own public IP, a server-side proxy is required to: + +1. Receive the request from the browser +2. Extract the client IP from the incoming connection +3. Forward the request to the LocID Encrypt API with the IP injected +4. Return the response with `tx_cloc` and `connection_ip` to the browser (any `stable_cloc` is ignored client-side) + +This architecture ensures the browser never transmits IP addresses and the LocID service receives accurate location data. + +If you configure `altId`, the module appends it as `?alt_id=` to the endpoint URL. Your proxy can then forward this to the LocID API. + +### CORS Configuration + +If your endpoint is on a different origin or you set `withCredentials: true`, ensure your server returns appropriate CORS headers: + +```http +Access-Control-Allow-Origin: +Access-Control-Allow-Credentials: true +``` + +When using `withCredentials`, the server cannot use `Access-Control-Allow-Origin: *`; it must specify the exact origin. + +### Storage Configuration + +| Parameter | Required | Description | +| --------- | -------- | ---------------- | +| `type` | Yes | `'html5'` | +| `name` | Yes | Storage key name | +| `expires` | No | TTL in days | + +### Stored Value Format + +The module stores a structured object (rather than a raw string) so it can track IP-aware metadata: + +```json +{ + "id": "", + "connectionIp": "203.0.113.42", + "createdAt": 1738147200000, + "updatedAt": 1738147200000, + "expiresAt": 1738752000000 +} +``` + +When the endpoint returns a valid `connection_ip` but no usable `tx_cloc` (`null`, missing, empty, or whitespace-only), `id` is stored as `null`. This caches the "no location for this IP" result for the full cache period without re-fetching. The `decode()` function returns `undefined` for `null` IDs, so no EID is emitted in bid requests. + +**Important:** String-only stored values are treated as invalid and are not emitted. + +### IP Cache Format + +The module maintains a separate IP cache entry in localStorage (default key: `{storage.name}_ip`) with a shorter TTL (default 4 hours): + +```json +{ + "ip": "203.0.113.42", + "fetchedAt": 1738147200000, + "expiresAt": 1738161600000 +} +``` + +This entry is managed by the module directly via Prebid's `storageManager` and is independent of the framework-managed tx_cloc cache. + +## Operation Flow + +The module uses a two-tier cache: an IP cache (default 4-hour TTL) and a tx_cloc cache (TTL defined by `storage.expires`). The IP is refreshed more frequently to detect network changes while keeping tx_cloc stable for its full cache period. + +1. The module checks the IP cache for a current connection IP. +2. If the IP cache is valid, the module compares it against the stored tx_cloc entry's `connectionIp`. +3. If the IPs match and the tx_cloc entry is not expired, the cached tx_cloc is reused (even if `null`). +4. If the IP cache is expired or missing and `ipEndpoint` is configured, the module calls `ipEndpoint` to get the current IP, then compares with the stored tx_cloc. If the IPs match, the tx_cloc is reused without calling the main endpoint. +5. If the IPs differ, or the tx_cloc is expired/missing, or `ipEndpoint` is not configured, the module calls the main endpoint to get a fresh tx_cloc and connection IP. +6. The endpoint response may include a `null`, empty, whitespace-only, or missing `tx_cloc` (indicating no location for this IP). This is cached as `id: null` for the full cache period, and overrides any previously stored non-null ID for that same IP. +7. Both the IP cache and tx_cloc cache are updated after each endpoint call. +8. The ID is included in bid requests via the EIDs array. Entries with `null` tx_cloc are omitted from bid requests. + +## Endpoint Response Requirements + +The proxy must return: + +```json +{ + "tx_cloc": "", + "connection_ip": "203.0.113.42" +} +``` + +Notes: + +- `connection_ip` is always required. If missing, the entire response is treated as a failure. +- `tx_cloc` may be `null`, missing, empty, or whitespace-only when no location is available for the IP. This is a valid response and will be cached as `id: null` for the configured cache period. +- `tx_cloc` is the only value the browser module will store/transmit. +- `stable_cloc` may exist in proxy responses for server-side caching, but the client ignores it. + +## IP Change Detection + +The module uses a two-tier cache to detect IP changes without churning the tx_cloc identifier: + +- **IP cache** (default 4-hour TTL): Tracks the current connection IP. Stored in a separate localStorage key (`{storage.name}_ip`). +- **tx_cloc cache** (`storage.expires`): Stores the LocID. Managed by Prebid's userId framework. + +When the IP cache expires, the module refreshes the IP. If the IP is unchanged and the tx_cloc cache is still valid, the existing tx_cloc is reused without calling the main endpoint. + +### ipEndpoint (optional) + +When `ipEndpoint` is configured, the module calls it for lightweight IP-only checks. This avoids a full tx_cloc API call when only the IP needs refreshing. The endpoint should return the connection IP in one of these formats: + +- JSON: `{"ip": "203.0.113.42"}` or `{"connection_ip": "203.0.113.42"}` +- Plain text: `203.0.113.42` + +If `apiKey` is configured, the `x-api-key` header is included on `ipEndpoint` requests using the same `customHeaders` mechanism as the main endpoint. + +When `ipEndpoint` is not configured, the module falls back to calling the main endpoint to refresh the IP, but only updates the stored tx_cloc when the IP has changed or the tx_cloc cache has expired. In this mode, IP changes are only detected when the IP cache is refreshed (for example when it expires and `extendId()` returns a refresh callback); there is no separate lightweight proactive IP probe. + +### Prebid Refresh Triggers + +When `storage.refreshInSeconds` is set, the module will reuse the cached ID until `createdAt + refreshInSeconds`; once due (or if `createdAt` is missing), `extendId()` returns `undefined` to indicate the cached ID should not be reused. The `extendId()` method also checks the IP cache: if the IP cache is expired or missing, or if the cached IP differs from the stored tx_cloc's IP, it returns a callback that refreshes via the main endpoint. This enforces the IP cache TTL (`ipCacheTtlMs`) even when the tx_cloc cache has not expired. + +## Consent Handling + +LocID operates under Legitimate Interest (LI). By default, the module proceeds when no privacy framework signals are present. When privacy signals exist, they are enforced. Privacy frameworks can only stop LocID via global processing restrictions; they do not enable it. +For TCF integration, the module declares Prebid's vendorless GVL marker so purpose-level enforcement applies without vendor-ID checks. + +### Legal Basis and IP-Based Identifiers + +LocID is derived from IP-based geolocation. Because IP addresses are transient and shared, there is no meaningful IP-level choice to express. Privacy frameworks are only consulted to honor rare, publisher- or regulator-level instructions to stop all processing. When such a global processing restriction is signaled, LocID respects it by returning `undefined`. + +### Default Behavior (allowWithoutSignals) + +- **No privacy signals present**: Module proceeds and fetches the ID +- **Privacy signals present**: Enforcement rules apply (see below) + +### Strict Mode (requireSignals) + +Set `requirePrivacySignals: true` or `privacyMode: 'requireSignals'` to require privacy signals: + +```javascript +params: { + endpoint: 'https://id.example.com/locid', + requirePrivacySignals: true +} +``` + +In strict mode, the module returns `undefined` if no privacy signals are present. + +### Privacy Signal Enforcement + +When privacy signals **are** present, the module does not fetch or return an ID if any of the following apply: + +- GDPR applies and vendorData is present, but consentString is missing or empty +- The US Privacy string indicates a global processing restriction (third character is 'Y') +- GPP signals indicate an applicable processing restriction + +When GDPR applies and `consentString` is present, the module proceeds unless a framework processing restriction is signaled. + +### Privacy Signals Detection + +The module considers privacy signals "present" if any of the following exist: + +- `consentString` (TCF consent string from CMP) +- `vendorData` (TCF vendor data from CMP) +- `usp` or `uspConsent` (US Privacy string) +- `gpp` or `gppConsent` (GPP consent data) +- Data from `uspDataHandler` or `gppDataHandler` + +**Important:** `gdprApplies` alone does NOT constitute a privacy signal. A publisher may indicate GDPR jurisdiction without having a CMP installed. TCF framework data is only required when actual CMP artifacts (`consentString` or `vendorData`) are present. This supports Legitimate Interest-based operation in deployments without a full TCF implementation. + +## EID Output + +When available, the LocID is exposed as: + +```javascript +{ + source: "locid.com", + uids: [{ + id: "", + atype: 1 // AdCOM AgentTypeWeb + }] +} +``` + +## Identifier Type + +- **`atype: 1`** — The AdCOM agent type for web (`AgentTypeWeb`). This is used in EID emission. + +`atype` is an OpenRTB agent type (environment), not an IAB GVL vendor ID. + +## Debugging + +```javascript +pbjs.getUserIds().locId +pbjs.refreshUserIds() +localStorage.getItem('_locid') +localStorage.getItem('_locid_ip') // IP cache entry +``` + +## Validation Checklist + +- [ ] EID is present in bid requests when no processing restriction is signaled +- [ ] No network request occurs when a global processing restriction is signaled +- [ ] Stored IDs are reused across page loads diff --git a/modules/lockerdomeBidAdapter.js b/modules/lockerdomeBidAdapter.js index e0be50e6d1c..59c90e3f532 100644 --- a/modules/lockerdomeBidAdapter.js +++ b/modules/lockerdomeBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getBidIdParameter} from '../src/utils.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getBidIdParameter } from '../src/utils.js'; export const spec = { code: 'lockerdome', diff --git a/modules/logicadBidAdapter.js b/modules/logicadBidAdapter.js index 64a848c157e..18aac8faa0d 100644 --- a/modules/logicadBidAdapter.js +++ b/modules/logicadBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { deepAccess } from '../src/utils.js'; diff --git a/modules/loopmeBidAdapter.js b/modules/loopmeBidAdapter.js index 0cdf03b5f56..8edb980033d 100644 --- a/modules/loopmeBidAdapter.js +++ b/modules/loopmeBidAdapter.js @@ -16,7 +16,7 @@ export const converter = ortbConverter({ }, imp(buildImp, bidRequest, context) { const imp = buildImp(bidRequest, context); - deepSetValue(imp, 'ext.bidder', {...bidRequest.params}); + deepSetValue(imp, 'ext.bidder', { ...bidRequest.params }); return imp; }, request(buildRequest, imps, bidderRequest, context) { @@ -31,19 +31,19 @@ export const spec = { code: BIDDER_CODE, gvlid: GVLID, - isBidRequestValid: ({params = {}}) => Boolean(params.publisherId), + isBidRequestValid: ({ params = {} }) => Boolean(params.publisherId), buildRequests: (bidRequests, bidderRequest) => - ({url, method: 'POST', data: converter.toORTB({bidRequests, bidderRequest})}), + ({ url, method: 'POST', data: converter.toORTB({ bidRequests, bidderRequest }) }), - interpretResponse: ({body}, {data}) => converter.fromORTB({ request: data, response: body }).bids, + interpretResponse: ({ body }, { data }) => converter.fromORTB({ request: data, response: body }).bids, getUserSyncs: (syncOptions, serverResponses) => - serverResponses.flatMap(({body}) => + serverResponses.flatMap(({ body }) => (body.ext?.usersyncs || []) - .filter(({type}) => type === 'image' || type === 'iframe') - .filter(({url}) => url && (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('//'))) - .filter(({type}) => (type === 'image' && syncOptions.pixelEnabled) || (type === 'iframe' && syncOptions.iframeEnabled)) + .filter(({ type }) => type === 'image' || type === 'iframe') + .filter(({ url }) => url && (url.startsWith('http://') || url.startsWith('https://') || url.startsWith('//'))) + .filter(({ type }) => (type === 'image' && syncOptions.pixelEnabled) || (type === 'iframe' && syncOptions.iframeEnabled)) ) } registerBidder(spec); diff --git a/modules/lotamePanoramaIdSystem.js b/modules/lotamePanoramaIdSystem.js index b3a356dbc66..aeccc5ac6b5 100644 --- a/modules/lotamePanoramaIdSystem.js +++ b/modules/lotamePanoramaIdSystem.js @@ -15,8 +15,8 @@ import { } from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -38,7 +38,7 @@ const ID_HOST = 'id.crwdcntrl.net'; const ID_HOST_COOKIELESS = 'c.ltmsphrcl.net'; const DO_NOT_HONOR_CONFIG = false; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); let cookieDomain; const appliedConfig = { name: 'lotamePanoramaId', diff --git a/modules/luceadBidAdapter.js b/modules/luceadBidAdapter.js index 134b6e505eb..78016f9fa56 100755 --- a/modules/luceadBidAdapter.js +++ b/modules/luceadBidAdapter.js @@ -2,10 +2,10 @@ * @module modules/luceadBidAdapter */ -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getUniqueIdentifierStr, deepSetValue, logInfo} from '../src/utils.js'; -import {fetch} from '../src/ajax.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getUniqueIdentifierStr, deepSetValue, logInfo } from '../src/utils.js'; +import { fetch } from '../src/ajax.js'; const bidderCode = 'lucead'; const defaultCurrency = 'EUR'; @@ -105,7 +105,7 @@ function interpretResponse(serverResponse, bidRequest) { }, })); - logInfo('interpretResponse', {serverResponse, bidRequest, bidRequestData, bids}); + logInfo('interpretResponse', { serverResponse, bidRequest, bidRequestData, bids }); if (response?.enable_pa === false) { return bids; } @@ -133,7 +133,7 @@ function interpretResponse(serverResponse, bidRequest) { } })); - return {bids, paapi: fledgeAuctionConfigs}; + return { bids, paapi: fledgeAuctionConfigs }; } function report(type, data) { diff --git a/modules/luponmediaBidAdapter.js b/modules/luponmediaBidAdapter.js index 2e22e10d1cd..a208ed3f831 100755 --- a/modules/luponmediaBidAdapter.js +++ b/modules/luponmediaBidAdapter.js @@ -1,8 +1,8 @@ -import {logError, logMessage, logWarn, deepSetValue} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {config} from '../src/config.js'; +import { logError, logMessage, logWarn, deepSetValue } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { config } from '../src/config.js'; const BIDDER_CODE = 'luponmedia'; const GVLID = 1132; @@ -102,7 +102,7 @@ export const spec = { }; }, interpretResponse: (response, request) => { - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; }, getUserSyncs: function (syncOptions, responses) { const allUserSyncs = []; diff --git a/modules/madvertiseBidAdapter.js b/modules/madvertiseBidAdapter.js index 183fca096c3..2d0c0f7ad3a 100644 --- a/modules/madvertiseBidAdapter.js +++ b/modules/madvertiseBidAdapter.js @@ -1,5 +1,5 @@ import { parseSizesInput, _each } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -65,7 +65,7 @@ export const spec = { return { method: 'GET', url: MADVERTISE_ENDPOINT + src, - options: {withCredentials: false}, + options: { withCredentials: false }, bidId: bidRequest.bidId }; }); diff --git a/modules/magniteAnalyticsAdapter.js b/modules/magniteAnalyticsAdapter.js index cc275bd59f0..bf28dab4fea 100644 --- a/modules/magniteAnalyticsAdapter.js +++ b/modules/magniteAnalyticsAdapter.js @@ -20,11 +20,11 @@ import { import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS, REJECTION_REASON } from '../src/constants.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; import { getHook } from '../src/hook.js'; const RUBICON_GVL_ID = 52; @@ -1021,7 +1021,7 @@ magniteAdapter.track = ({ eventType, args }) => { }; const handlePbsAnalytics = function (args) { - const {seatnonbid, auctionId, atag} = args; + const { seatnonbid, auctionId, atag } = args; if (seatnonbid) { handleNonBidEvent(seatnonbid, auctionId); } @@ -1049,10 +1049,10 @@ const handleNonBidEvent = function(seatnonbid, auctionId) { } const adUnits = auction.adUnits; seatnonbid.forEach(seatnonbid => { - const {seat} = seatnonbid; + const { seat } = seatnonbid; seatnonbid.nonbid.forEach(nonbid => { try { - const {status, impid} = nonbid; + const { status, impid } = nonbid; const matchingTid = Object.keys(adUnits).find(tid => adUnits[tid].adUnitCode === impid); const adUnit = adUnits[matchingTid]; const statusInfo = statusMap[status] || { status: 'no-bid' }; diff --git a/modules/malltvAnalyticsAdapter.js b/modules/malltvAnalyticsAdapter.js index 29936d18a0b..98aa989cc15 100644 --- a/modules/malltvAnalyticsAdapter.js +++ b/modules/malltvAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax.js' +import { ajax } from '../src/ajax.js' import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js' import { EVENTS } from '../src/constants.js' import adapterManager from '../src/adapterManager.js' -import {getGlobal} from '../src/prebidGlobal.js' -import {logInfo, logError, deepClone} from '../src/utils.js' +import { getGlobal } from '../src/prebidGlobal.js' +import { logInfo, logError, deepClone } from '../src/utils.js' const analyticsType = 'endpoint' export const ANALYTICS_VERSION = '1.0.0' @@ -40,7 +40,7 @@ export const parseAdUnitCode = function (bidResponse) { return bidResponse.adUnitCode.toLowerCase() } -export const malltvAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, analyticsType}), { +export const malltvAnalyticsAdapter = Object.assign(adapter({ DEFAULT_SERVER, analyticsType }), { cachedAuctions: {}, @@ -62,7 +62,7 @@ export const malltvAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, ana return true }, - track({eventType, args}) { + track({ eventType, args }) { switch (eventType) { case BID_TIMEOUT: this.handleBidTimeout(args) @@ -86,7 +86,7 @@ export const malltvAnalyticsAdapter = Object.assign(adapter({DEFAULT_SERVER, ana ) }, createBidMessage(auctionEndArgs, winningBids, timeoutBids) { - const {auctionId, timestamp, timeout, auctionEnd, adUnitCodes, bidsReceived, noBids} = auctionEndArgs + const { auctionId, timestamp, timeout, auctionEnd, adUnitCodes, bidsReceived, noBids } = auctionEndArgs const message = this.createCommonMessage(auctionId) message.auctionElapsed = (auctionEnd - timestamp) diff --git a/modules/malltvBidAdapter.js b/modules/malltvBidAdapter.js index ef71f367142..5ad83875a7a 100644 --- a/modules/malltvBidAdapter.js +++ b/modules/malltvBidAdapter.js @@ -16,7 +16,7 @@ const SIZE_SEPARATOR = ';'; const BISKO_ID = 'biskoId'; const STORAGE_ID = 'bisko-sid'; const SEGMENTS = 'biskoSegments'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/mantisBidAdapter.js b/modules/mantisBidAdapter.js index 5d9ccc9419b..a65225b0724 100644 --- a/modules/mantisBidAdapter.js +++ b/modules/mantisBidAdapter.js @@ -1,10 +1,10 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; import { ajax } from '../src/ajax.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; import { getWinDimensions } from '../src/utils.js'; -export const storage = getStorageManager({bidderCode: 'mantis'}); +export const storage = getStorageManager({ bidderCode: 'mantis' }); function inIframe() { try { @@ -220,7 +220,7 @@ export const spec = { bidId: bid.bidId, config: bid.params, sizes: bid.sizes.map(function (size) { - return {width: size[0], height: size[1]}; + return { width: size[0], height: size[1] }; }) }; }), @@ -261,13 +261,13 @@ export const spec = { if (syncOptions.iframeEnabled) { return [{ type: 'iframe', - url: buildMantisUrl('/prebid/iframe', {gdpr: gdprConsent, uspConsent: uspConsent}) + url: buildMantisUrl('/prebid/iframe', { gdpr: gdprConsent, uspConsent: uspConsent }) }]; } if (syncOptions.pixelEnabled) { return [{ type: 'image', - url: buildMantisUrl('/prebid/pixel', {gdpr: gdprConsent, uspConsent: uspConsent}) + url: buildMantisUrl('/prebid/pixel', { gdpr: gdprConsent, uspConsent: uspConsent }) }]; } } diff --git a/modules/marsmediaBidAdapter.js b/modules/marsmediaBidAdapter.js index 3a7039d7899..633f5c380ff 100644 --- a/modules/marsmediaBidAdapter.js +++ b/modules/marsmediaBidAdapter.js @@ -1,11 +1,11 @@ 'use strict'; -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, parseSizesInput, isArray, getWindowTop, deepSetValue, triggerPixel, getWindowSelf, isPlainObject } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { config } from '../src/config.js'; import { percentInView } from '../libraries/percentInView/percentInView.js'; -import {getMinSize} from '../libraries/sizeUtils/sizeUtils.js'; +import { getMinSize } from '../libraries/sizeUtils/sizeUtils.js'; function MarsmediaAdapter() { this.code = 'marsmedia'; @@ -165,7 +165,7 @@ function MarsmediaAdapter() { let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]); bidSizes = bidSizes.filter(size => isArray(size)); - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); + const processedSizes = bidSizes.map(size => ({ w: parseInt(size[0], 10), h: parseInt(size[1], 10) })); const element = document.getElementById(bid.adUnitCode); const minSize = getMinSize(processedSizes); diff --git a/modules/mediaeyesBidAdapter.js b/modules/mediaeyesBidAdapter.js index ae43af2b50d..c0cac81db31 100644 --- a/modules/mediaeyesBidAdapter.js +++ b/modules/mediaeyesBidAdapter.js @@ -20,7 +20,7 @@ export const spec = { const requests = []; bidRequests.forEach(bidRequest => { - const {itemId} = bidRequest.params; + const { itemId } = bidRequest.params; const requestData = { id: generateUUID(), imp: [cookingImp(bidRequest)], diff --git a/modules/mediaforceBidAdapter.js b/modules/mediaforceBidAdapter.js index a1d333ab0af..fa728d01944 100644 --- a/modules/mediaforceBidAdapter.js +++ b/modules/mediaforceBidAdapter.js @@ -1,7 +1,7 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, isStr, replaceAuctionPrice, triggerPixel, parseGPTSingleSizeArrayToRtbSize } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { buildNativeRequest, parseNativeResponse } from '../libraries/nativeAssetsUtils.js'; diff --git a/modules/mediafuseBidAdapter.js b/modules/mediafuseBidAdapter.js index 0bffb9219ce..da98d88fa81 100644 --- a/modules/mediafuseBidAdapter.js +++ b/modules/mediafuseBidAdapter.js @@ -16,22 +16,22 @@ import { logMessage, logWarn } from '../src/utils.js'; -import {Renderer} from '../src/Renderer.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ADPOD, BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {bidderSettings} from '../src/bidderSettings.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {APPNEXUS_CATEGORY_MAPPING} from '../libraries/categoryTranslationMapping/index.js'; +import { Renderer } from '../src/Renderer.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ADPOD, BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { bidderSettings } from '../src/bidderSettings.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { APPNEXUS_CATEGORY_MAPPING } from '../libraries/categoryTranslationMapping/index.js'; import { getANKewyordParamFromMaps, getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; -import {convertCamelToUnderscore, fill} from '../libraries/appnexusUtils/anUtils.js'; -import {chunk} from '../libraries/chunk/chunk.js'; +import { convertCamelToUnderscore, fill } from '../libraries/appnexusUtils/anUtils.js'; +import { chunk } from '../libraries/chunk/chunk.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -88,7 +88,7 @@ const SCRIPT_TAG_START = ' { if (isNumber(val)) { - segs.push({'id': val}); + segs.push({ 'id': val }); } else if (isPlainObject(val)) { segs.push(val); } @@ -276,7 +276,7 @@ export const spec = { bidRequests[0].userIdAsEids.forEach(eid => { if (!eid || !eid.uids || eid.uids.length < 1) { return; } eid.uids.forEach(uid => { - const tmp = {'source': eid.source, 'id': uid.id}; + const tmp = { 'source': eid.source, 'id': uid.id }; if (eid.source === 'adserver.org') { tmp.rti_partner = 'TDID'; } else if (eid.source === 'uidapi.com') { @@ -348,7 +348,7 @@ export const spec = { }, getUserSyncs: function (syncOptions, responses, gdprConsent) { - if (syncOptions.iframeEnabled && hasPurpose1Consent({gdprConsent})) { + if (syncOptions.iframeEnabled && hasPurpose1Consent({ gdprConsent })) { return [{ type: 'iframe', url: 'https://acdn.adnxs.com/dmp/async_usersync.html' @@ -565,12 +565,13 @@ function newBid(serverBid, rtbBid, bidderRequest) { complete: 0, nodes: [{ bsid: rtbBid.buyer_member_id.toString() - }]}; + }] + }; return dchain; } if (rtbBid.buyer_member_id) { - bid.meta = Object.assign({}, bid.meta, {dchain: setupDChain(rtbBid)}); + bid.meta = Object.assign({}, bid.meta, { dchain: setupDChain(rtbBid) }); } if (rtbBid.brand_id) { diff --git a/modules/mediagoBidAdapter.js b/modules/mediagoBidAdapter.js index c5fd2189cb9..fd681c2fccc 100644 --- a/modules/mediagoBidAdapter.js +++ b/modules/mediagoBidAdapter.js @@ -10,6 +10,7 @@ import { getDevice } from '../libraries/fpdUtils/deviceInfo.js'; import { getBidFloor } from '../libraries/currencyUtils/floor.js'; import { transformSizes, normalAdSize } from '../libraries/sizeUtils/tranformSize.js'; import { getHLen } from '../libraries/navigatorData/navigatorData.js'; +import { getOsInfo } from '../libraries/nexverseUtils/index.js'; import { cookieSync } from '../libraries/cookieSync/cookieSync.js'; // import { config } from '../src/config.js'; @@ -31,7 +32,7 @@ export const THIRD_PARTY_COOKIE_ORIGIN = 'https://cdn.mediago.io'; const TIME_TO_LIVE = 500; const GVLID = 1020; // const ENDPOINT_URL = '/api/bid?tn='; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const globals = {}; /* ----- mguid:start ------ */ @@ -42,8 +43,7 @@ const COOKY_SYNC_IFRAME_URL = 'https://cdn.mediago.io/js/cookieSync.html'; let reqTimes = 0; /** - * get pmg uid - * 获取并生成用户的id + * Get or generate pmg uid * * @return {string} */ @@ -63,10 +63,10 @@ export const getPmgUID = () => { /* ----- pmguid:end ------ */ /** - * 获取一个对象的某个值,如果没有则返回空字符串 + * Get a nested property value from object, return empty string if not found * - * @param {Object} obj 对象 - * @param {...string} keys 键名 + * @param {Object} obj object + * @param {...string} keys key path * @return {any} */ function getProperty(obj, ...keys) { @@ -84,7 +84,21 @@ function getProperty(obj, ...keys) { } /** - * 获取底价 + * Retrieve device platform/OS, priority order: userAgentData.platform > navigator.platform > UA parsing + * @returns {string} + */ +function getDeviceOs() { + if (navigator.userAgentData?.platform) { + return navigator.userAgentData.platform; + } + if (navigator.platform) { + return navigator.platform; + } + return getOsInfo().os || ''; +} + +/** + * Get bid floor * @param {*} bid * @param {*} mediaType * @param {*} sizes @@ -106,11 +120,11 @@ function getProperty(obj, ...keys) { // return floor; // } -// 支持的广告尺寸 +// Supported ad sizes const mediagoAdSize = normalAdSize; /** - * 获取广告位配置 + * Get ad slot config * @param {Array} validBidRequests an an array of bids * @param {Object} bidderRequest The master bidRequest object * @return {Object} @@ -124,7 +138,7 @@ function getItems(validBidRequests, bidderRequest) { const sizes = transformSizes(getProperty(req, 'sizes')); let matchSize; - // 确认尺寸是否符合我们要求 + // Validate size meets requirements for (const size of sizes) { matchSize = mediagoAdSize.find(item => size.width === item.w && size.height === item.h); if (matchSize) { @@ -153,7 +167,7 @@ function getItems(validBidRequests, bidderRequest) { } // if (mediaTypes.native) {} - // banner广告类型 + // Banner ad type if (mediaTypes.banner) { // fix id is not unique where there are multiple requests in the same page const id = getProperty(req, 'bidId') || ('' + (i + 1) + Math.random().toString(36).substring(2, 15)); @@ -169,10 +183,11 @@ function getItems(validBidRequests, bidderRequest) { ext: { adUnitCode: req.adUnitCode, referrer: getReferrer(req, bidderRequest), - ortb2Imp: utils.deepAccess(req, 'ortb2Imp'), // 传入完整对象,分析日志数据 - gpid: gpid, // 加入后无法返回广告 + ortb2Imp: utils.deepAccess(req, 'ortb2Imp'), + gpid: gpid, adslot: utils.deepAccess(req, 'ortb2Imp.ext.data.adserver.adslot', '', ''), publisher: req.params.publisher || '', + transactionId: utils.deepAccess(req, 'ortb2Imp.ext.tid') || req.transactionId || '', ...gdprConsent // gdpr }, tagid: req.params && req.params.tagid @@ -195,7 +210,7 @@ export function getCurrentTimeToUTCString() { } /** - * 获取rtb请求参数 + * Get RTB request params * * @param {Array} validBidRequests an an array of bids * @param {Object} bidderRequest The master bidRequest object @@ -240,11 +255,12 @@ function getParam(validBidRequests, bidderRequest) { // language: 'en', // os: 'Microsoft Windows', // ua: 'Mozilla/5.0 (Linux; Android 12; SM-G970U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Mobile Safari/537.36', - os: navigator.platform || '', + os: getDeviceOs(), ua: navigator.userAgent, language: /en/.test(navigator.language) ? 'en' : navigator.language }, ext: { + pbjsversion: '$prebid.version$', eids, bidsUserIdAsEids, firstPartyData, diff --git a/modules/mediakeysBidAdapter.js b/modules/mediakeysBidAdapter.js index a4eeb591d90..4aed102c6dc 100644 --- a/modules/mediakeysBidAdapter.js +++ b/modules/mediakeysBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { cleanObj, deepAccess, @@ -17,10 +17,10 @@ import { mergeDeep, triggerPixel } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const AUCTION_TYPE = 1; const BIDDER_CODE = 'mediakeys'; @@ -81,7 +81,8 @@ const ORTB_VIDEO_PARAMS = { playbackend: value => [1, 2, 3].indexOf(value) !== -1, delivery: value => [1, 2, 3].indexOf(value) !== -1, pos: value => [0, 1, 2, 3, 4, 5, 6, 7].indexOf(value) !== -1, - api: value => Array.isArray(value) && value.every(v => [1, 2, 3, 4, 5, 6].indexOf(v) !== -1)}; + api: value => Array.isArray(value) && value.every(v => [1, 2, 3, 4, 5, 6].indexOf(v) !== -1) +}; /** * Returns the OpenRtb deviceType id detected from User Agent @@ -226,7 +227,7 @@ function createBannerImp(bid) { const format = []; sizes.forEach(function (size) { if (size.length && size.length > 1) { - format.push({w: size[0], h: size[1]}); + format.push({ w: size[0], h: size[1] }); } }); banner.format = format; diff --git a/modules/medianetAnalyticsAdapter.js b/modules/medianetAnalyticsAdapter.js index 734e2120b7b..56bef3e6a00 100644 --- a/modules/medianetAnalyticsAdapter.js +++ b/modules/medianetAnalyticsAdapter.js @@ -9,15 +9,15 @@ import { parseUrl, safeJSONEncode, } from '../src/utils.js'; -import {config} from '../src/config.js'; +import { config } from '../src/config.js'; import adapterManager from '../src/adapterManager.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {BID_STATUS, EVENTS, REJECTION_REASON, S2S, TARGETING_KEYS} from '../src/constants.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {ajax} from '../src/ajax.js'; -import {getPriceByGranularity} from '../src/auction.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; -import {registerVastTrackers} from '../libraries/vastTrackers/vastTrackers.js'; +import { BID_STATUS, EVENTS, REJECTION_REASON, S2S, TARGETING_KEYS } from '../src/constants.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { ajax } from '../src/ajax.js'; +import { getPriceByGranularity } from '../src/auction.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; +import { registerVastTrackers } from '../libraries/vastTrackers/vastTrackers.js'; import { filterBidsListByFilters, findBidObj, @@ -33,7 +33,7 @@ import { getLoggingPayload, shouldLogAPPR } from '../libraries/medianetUtils/logger.js'; -import {KeysMap} from '../libraries/medianetUtils/logKeys.js'; +import { KeysMap } from '../libraries/medianetUtils/logKeys.js'; import { LOGGING_DELAY, BID_FLOOR_REJECTED, @@ -64,7 +64,7 @@ import { WINNING_AUCTION_MISSING_ERROR, WINNING_BID_ABSENT_ERROR, ERROR_IWB_BID_MISSING, POST_ENDPOINT_RA } from '../libraries/medianetUtils/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { getGlobal } from '../src/prebidGlobal.js'; // General Constants const ADAPTER_CODE = 'medianetAnalytics'; @@ -393,7 +393,7 @@ function addS2sInfo(auctionObj, bidderRequests) { bidderRequest.bids.forEach((bidRequest) => { if (bidRequest.src !== S2S.SRC) return; - const bidObjs = filterBidsListByFilters(auctionObj.bidsReceived, {bidId: bidRequest.bidId}); + const bidObjs = filterBidsListByFilters(auctionObj.bidsReceived, { bidId: bidRequest.bidId }); bidObjs.forEach((bidObj) => { bidObj.serverLatencyMillis = bidderRequest.serverResponseTimeMs; @@ -785,11 +785,14 @@ function bidderDoneHandler(eventType, args) { } function adRenderFailedHandler(eventType, args) { - const {reason, message, bid: { - auctionId, - adUnitCode, - bidder, - creativeId}} = args; + const { + reason, message, bid: { + auctionId, + adUnitCode, + bidder, + creativeId + } + } = args; errorLogger(eventType, { reason, message, @@ -801,7 +804,7 @@ function adRenderFailedHandler(eventType, args) { } function adRenderSucceededHandler(eventType, args) { - const {bid: {auctionId, adUnitCode, bidder, creativeId}} = args; + const { bid: { auctionId, adUnitCode, bidder, creativeId } } = args; errorLogger(eventType, { auctionId, adUnitCode, diff --git a/modules/medianetBidAdapter.js b/modules/medianetBidAdapter.js index cec3880a6d7..3a98dcf57b9 100644 --- a/modules/medianetBidAdapter.js +++ b/modules/medianetBidAdapter.js @@ -10,19 +10,19 @@ import { deepClone, deepSetValue, getWindowTop } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; -import {getViewportCoordinates} from '../libraries/viewport/viewport.js'; -import {filterBidsListByFilters, getTopWindowReferrer} from '../libraries/medianetUtils/utils.js'; -import {errorLogger} from '../libraries/medianetUtils/logger.js'; -import {GLOBAL_VENDOR_ID, MEDIANET} from '../libraries/medianetUtils/constants.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {getBoundingClientRect} from '../libraries/boundingClientRect/boundingClientRect.js'; -import {getMinSize} from '../libraries/sizeUtils/sizeUtils.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; +import { getViewportCoordinates } from '../libraries/viewport/viewport.js'; +import { filterBidsListByFilters, getTopWindowReferrer } from '../libraries/medianetUtils/utils.js'; +import { errorLogger } from '../libraries/medianetUtils/logger.js'; +import { GLOBAL_VENDOR_ID, MEDIANET } from '../libraries/medianetUtils/constants.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; +import { getMinSize } from '../libraries/sizeUtils/sizeUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -137,7 +137,7 @@ function getCoordinates(adUnitCode) { let element = document.getElementById(adUnitCode); if (!element && adUnitCode.indexOf('/') !== -1) { // now it means that adUnitCode is GAM AdUnitPath - const {divId} = getGptSlotInfoForAdUnitCode(adUnitCode); + const { divId } = getGptSlotInfoForAdUnitCode(adUnitCode); if (isStr(divId)) { element = document.getElementById(divId); } @@ -168,7 +168,7 @@ function extParams(bidRequest, bidderRequests) { const gdprApplies = !!(gdpr && gdpr.gdprApplies); const uspApplies = !!(uspConsent); const coppaApplies = !!(config.getConfig('coppa')); - const {top = -1, right = -1, bottom = -1, left = -1} = getViewportCoordinates(); + const { top = -1, right = -1, bottom = -1, left = -1 } = getViewportCoordinates(); return Object.assign({}, { customer_id: params.cid }, { prebid_version: 'v' + '$prebid.version$' }, @@ -176,11 +176,11 @@ function extParams(bidRequest, bidderRequests) { (gdprApplies) && { gdpr_consent_string: gdpr.consentString || '' }, { usp_applies: uspApplies }, uspApplies && { usp_consent_string: uspConsent || '' }, - {coppa_applies: coppaApplies}, + { coppa_applies: coppaApplies }, windowSize.w !== -1 && windowSize.h !== -1 && { screen: windowSize }, userId && { user_id: userId }, getGlobal().medianetGlobals.analyticsEnabled && { analytics: true }, - !isEmpty(sChain) && {schain: sChain}, + !isEmpty(sChain) && { schain: sChain }, { vcoords: { top_left: { x: left, y: top }, @@ -282,7 +282,7 @@ function getBidFloorByType(bidRequest) { return floorInfo; } function setFloorInfo(bidRequest, mediaType, size, floorInfo) { - const floor = bidRequest.getFloor({currency: 'USD', mediaType: mediaType, size: size}) || {}; + const floor = bidRequest.getFloor({ currency: 'USD', mediaType: mediaType, size: size }) || {}; if (size.length > 1) floor.size = size; floor.mediaType = mediaType; floorInfo.push(floor); @@ -299,7 +299,7 @@ function getSlotVisibility(topLeft, size) { return 0; } - return getOverlapArea(topLeft, bottomRight, {x: 0, y: 0}, {x: windowSize.w, y: windowSize.h}) / maxArea; + return getOverlapArea(topLeft, bottomRight, { x: 0, y: 0 }, { x: windowSize.w, y: windowSize.h }) / maxArea; } // find the overlapping area between two rectangles @@ -313,7 +313,7 @@ function getOverlapArea(topLeft1, bottomRight1, topLeft2, bottomRight2) { } function normalizeCoordinates(coordinates) { - const {scrollX, scrollY} = window; + const { scrollX, scrollY } = window; return { top_left: { x: coordinates.top_left.x + scrollX, @@ -508,7 +508,7 @@ export const spec = { return validBids; } if (ortbAuctionConfigs.length > 0) { - fledgeAuctionConfigs.push(...ortbAuctionConfigs.map(({igs}) => igs || []).flat()); + fledgeAuctionConfigs.push(...ortbAuctionConfigs.map(({ igs }) => igs || []).flat()); } return { bids: validBids, @@ -519,11 +519,11 @@ export const spec = { const cookieSyncUrls = fetchCookieSyncUrls(serverResponses); if (syncOptions.iframeEnabled) { - return filterBidsListByFilters(cookieSyncUrls, {type: 'iframe'}); + return filterBidsListByFilters(cookieSyncUrls, { type: 'iframe' }); } if (syncOptions.pixelEnabled) { - return filterBidsListByFilters(cookieSyncUrls, {type: 'image'}); + return filterBidsListByFilters(cookieSyncUrls, { type: 'image' }); } }, @@ -567,7 +567,7 @@ export const spec = { } catch (e) {} }, - onBidderError: ({error, bidderRequest}) => { + onBidderError: ({ error, bidderRequest }) => { try { const eventData = { name: EVENTS.BIDDER_ERROR, diff --git a/modules/medianetRtdProvider.js b/modules/medianetRtdProvider.js index a9a0bb47d63..b22b46625a7 100644 --- a/modules/medianetRtdProvider.js +++ b/modules/medianetRtdProvider.js @@ -1,7 +1,7 @@ -import {isEmptyStr, isFn, isStr, logError, mergeDeep} from '../src/utils.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {submodule} from '../src/hook.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { isEmptyStr, isFn, isStr, logError, mergeDeep } from '../src/utils.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { submodule } from '../src/hook.js'; +import { getGlobal } from '../src/prebidGlobal.js'; import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; @@ -26,7 +26,7 @@ function init(config) { executeCommand(() => window.mnjs.setData({ module: 'iref', name: 'initIRefresh', - data: {config, prebidGlobal: getGlobal()}, + data: { config, prebidGlobal: getGlobal() }, }, SOURCE)); return true; } @@ -34,7 +34,7 @@ function init(config) { function getBidRequestData(requestBidsProps, callback, config, userConsent) { executeCommand(() => { const adUnits = getAdUnits(requestBidsProps.adUnits, requestBidsProps.adUnitCodes); - const request = window.mnjs.onPrebidRequestBid({requestBidsProps, config, userConsent}); + const request = window.mnjs.onPrebidRequestBid({ requestBidsProps, config, userConsent }); if (!request) { callback(); return; @@ -56,7 +56,7 @@ function onAuctionInitEvent(auctionInit) { executeCommand(() => window.mnjs.setData({ module: 'iref', name: 'auctionInit', - data: {auction: auctionInit}, + data: { auction: auctionInit }, }, SOURCE)); } diff --git a/modules/mediasniperBidAdapter.js b/modules/mediasniperBidAdapter.js index eaf8e0606b2..2cf49393d17 100644 --- a/modules/mediasniperBidAdapter.js +++ b/modules/mediasniperBidAdapter.js @@ -15,8 +15,8 @@ import { triggerPixel, } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'mediasniper'; const DEFAULT_BID_TTL = 360; diff --git a/modules/mediasquareBidAdapter.js b/modules/mediasquareBidAdapter.js index cb358ec4687..dd91723af75 100644 --- a/modules/mediasquareBidAdapter.js +++ b/modules/mediasquareBidAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {Renderer} from '../src/Renderer.js'; +import { Renderer } from '../src/Renderer.js'; import { getRefererInfo } from '../src/refererDetection.js'; /** @@ -65,11 +65,11 @@ export const spec = { if (typeof adunitValue.getFloor === 'function') { if (Array.isArray(adunitValue.sizes)) { adunitValue.sizes.forEach(value => { - const tmpFloor = adunitValue.getFloor({currency: 'USD', mediaType: '*', size: value}); + const tmpFloor = adunitValue.getFloor({ currency: 'USD', mediaType: '*', size: value }); if (tmpFloor !== null && tmpFloor !== undefined && Object.keys(tmpFloor).length !== 0) { code.floor[value.join('x')] = tmpFloor; } }); } - const tmpFloor = adunitValue.getFloor({currency: 'USD', mediaType: '*', size: '*'}); + const tmpFloor = adunitValue.getFloor({ currency: 'USD', mediaType: '*', size: '*' }); if (tmpFloor !== null && tmpFloor !== undefined && Object.keys(tmpFloor).length !== 0) { code.floor['*'] = tmpFloor; } } if (adunitValue.ortb2Imp) { code.ortb2Imp = adunitValue.ortb2Imp } @@ -139,6 +139,9 @@ export const spec = { bidResponse['mediasquare'][param] = value[param]; } }); + if ('burls' in value) { + bidResponse['mediasquare']['burls'] = value['burls']; + } if ('native' in value) { bidResponse['native'] = value['native']; bidResponse['mediaType'] = 'native'; @@ -182,9 +185,22 @@ export const spec = { } const params = { pbjs: '$prebid.version$', referer: encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation) }; const endpoint = document.location.search.match(/msq_test=true/) ? BIDDER_URL_TEST : BIDDER_URL_PROD; - let paramsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment', 'ova']; + if (bid.hasOwnProperty('mediasquare')) { - paramsToSearchFor.forEach(param => { + // if burls then fire tracking pixels and exit + if (bid.mediasquare.hasOwnProperty('burls') && Array.isArray(bid.mediasquare.burls) && bid.mediasquare.burls.length > 0) { + bid.mediasquare.burls.forEach(burl => { + const url = burl && burl.url; + if (!url) return; + const method = (burl.method ?? "GET").toUpperCase(); + const data = (method === "POST" && burl.data ? burl.data : null); + ajax(url, null, data ? JSON.stringify(data) : null, { method: method, withCredentials: true }); + }); + return true; + } + // no burl so checking for other mediasquare params + let msqParamsToSearchFor = ['bidder', 'code', 'match', 'hasConsent', 'context', 'increment', 'ova']; + msqParamsToSearchFor.forEach(param => { if (bid['mediasquare'].hasOwnProperty(param)) { params[param] = bid['mediasquare'][param]; if (typeof params[param] === 'number') { @@ -193,7 +209,8 @@ export const spec = { } }); }; - paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency']; + + let paramsToSearchFor = ['cpm', 'size', 'mediaType', 'currency', 'creativeId', 'adUnitCode', 'timeToRespond', 'requestId', 'auctionId', 'originalCpm', 'originalCurrency']; paramsToSearchFor.forEach(param => { if (bid.hasOwnProperty(param)) { params[param] = bid[param]; @@ -202,7 +219,7 @@ export const spec = { } } }); - ajax(endpoint + BIDDER_ENDPOINT_WINNING, null, JSON.stringify(params), {method: 'POST', withCredentials: true}); + ajax(endpoint + BIDDER_ENDPOINT_WINNING, null, JSON.stringify(params), { method: 'POST', withCredentials: true }); return true; } diff --git a/modules/merkleIdSystem.js b/modules/merkleIdSystem.js index cc4bfbf5e98..166bb84b7e1 100644 --- a/modules/merkleIdSystem.js +++ b/modules/merkleIdSystem.js @@ -7,9 +7,9 @@ import { logInfo, logError, logWarn } from '../src/utils.js'; import * as ajaxLib from '../src/ajax.js'; -import {submodule} from '../src/hook.js' -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js' +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -23,7 +23,7 @@ const ID_URL = 'https://prebid.sv.rkdms.com/identity/'; const DEFAULT_REFRESH = 7 * 3600; const SESSION_COOKIE_NAME = '_svsid'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function getSession(configParams) { let session = null; @@ -85,7 +85,7 @@ function generateId(configParams, configStorage) { logError(`${MODULE_NAME}: merkleId fetch encountered an error`, error); callback(); }, - {method: 'GET', withCredentials: true} + { method: 'GET', withCredentials: true } ); }; return resp; @@ -111,14 +111,14 @@ export const merkleIdSubmodule = { logInfo('Merkle id ' + JSON.stringify(id)); if (id) { - return {'merkleId': id} + return { 'merkleId': id } } // Supports multiple IDs for different SSPs const merkleIds = (value && value?.merkleId && Array.isArray(value.merkleId)) ? value.merkleId : undefined; logInfo('merkleIds: ' + JSON.stringify(merkleIds)); - return merkleIds ? {'merkleId': merkleIds} : undefined; + return merkleIds ? { 'merkleId': merkleIds } : undefined; }, /** @@ -159,7 +159,7 @@ export const merkleIdSubmodule = { const configStorage = (config && config.storage) || {}; const resp = generateId(configParams, configStorage) - return {callback: resp}; + return { callback: resp }; }, extendId: function (config = {}, consentData, storedId) { logInfo('User ID - stored id ' + storedId); @@ -181,7 +181,7 @@ export const merkleIdSubmodule = { const configStorage = (config && config.storage) || {}; if (configStorage && configStorage.refreshInSeconds && typeof configParams.refreshInSeconds === 'number') { - return {id: storedId}; + return { id: storedId }; } let refreshInSeconds = DEFAULT_REFRESH; @@ -197,12 +197,12 @@ export const merkleIdSubmodule = { if (refreshNeeded) { logInfo('User ID - merkleId needs refreshing id'); const resp = generateId(configParams, configStorage); - return {callback: resp}; + return { callback: resp }; } } logInfo('User ID - merkleId not refreshed'); - return {id: storedId}; + return { id: storedId }; }, eids: { 'merkleId': { diff --git a/modules/mgidBidAdapter.js b/modules/mgidBidAdapter.js index 8044768bdad..367f9046184 100644 --- a/modules/mgidBidAdapter.js +++ b/modules/mgidBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { _each, deepAccess, @@ -18,9 +18,9 @@ import { isInteger, deepSetValue, getBidIdParameter, setOnAny, getWinDimensions } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getUserSyncs } from '../libraries/mgidUtils/mgidUtils.js' @@ -35,7 +35,7 @@ import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.j const GVLID = 358; const DEFAULT_CUR = 'USD'; const BIDDER_CODE = 'mgid'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const ENDPOINT_URL = 'https://prebid.mgid.com/prebid/'; const LOG_WARN_PREFIX = '[MGID warn]: '; const LOG_INFO_PREFIX = '[MGID info]: '; @@ -210,7 +210,7 @@ export const spec = { id: deepAccess(bidderRequest, 'bidderRequestId'), site: ortb2Data?.site || {}, cur: [cur], - geo: {utcoffset: info.timeOffset}, + geo: { utcoffset: info.timeOffset }, device: ortb2Data?.device || {}, ext: { mgid_ver: spec.VERSION, @@ -455,7 +455,7 @@ function createBannerRequest(bid) { if (sizes.length > 1) { for (let f = 0; f < sizes.length; f++) { if (sizes[f].length === 2) { - format.push({w: sizes[f][0], h: sizes[f][1]}); + format.push({ w: sizes[f][0], h: sizes[f][1] }); } } } @@ -692,7 +692,7 @@ function getBidFloor(bid, cur) { if (reqCur === cur) { cur = '' } - return {floor: bidFloor, cur: cur} + return { floor: bidFloor, cur: cur } } function copyFromAdmAsset(asset) { diff --git a/modules/mgidRtdProvider.js b/modules/mgidRtdProvider.js index 1ba75d3c343..f3b226182ae 100644 --- a/modules/mgidRtdProvider.js +++ b/modules/mgidRtdProvider.js @@ -1,9 +1,9 @@ import { submodule } from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import {deepAccess, logError, logInfo, mergeDeep} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { ajax } from '../src/ajax.js'; +import { deepAccess, logError, logInfo, mergeDeep } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule diff --git a/modules/michaoBidAdapter.ts b/modules/michaoBidAdapter.ts index 36ce72b7453..b16ac379aa8 100644 --- a/modules/michaoBidAdapter.ts +++ b/modules/michaoBidAdapter.ts @@ -1,5 +1,5 @@ import { ortbConverter } from '../libraries/ortbConverter/converter.js'; -import {type BidderSpec, registerBidder} from '../src/adapters/bidderFactory.js'; +import { type BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { Renderer } from '../src/Renderer.js'; import { diff --git a/modules/microadBidAdapter.js b/modules/microadBidAdapter.js index 4e292afebd2..b7564b597a5 100644 --- a/modules/microadBidAdapter.js +++ b/modules/microadBidAdapter.js @@ -23,15 +23,15 @@ const NATIVE_CODE = 2; const VIDEO_CODE = 4; const AUDIENCE_IDS = [ - {type: 6, bidKey: 'userId.imuid', source: 'intimatemerger.com'}, - {type: 8, bidKey: 'userId.id5id.uid', source: 'id5-sync.com'}, - {type: 9, bidKey: 'userId.tdid', source: 'adserver.org'}, - {type: 10, bidKey: 'userId.novatiq.snowflake', source: 'novatiq.com'}, - {type: 12, bidKey: 'userId.dacId.id', source: 'dac.co.jp'}, - {type: 13, bidKey: 'userId.idl_env', source: 'liveramp.com'}, - {type: 14, bidKey: 'userId.criteoId', source: 'criteo.com'}, - {type: 15, bidKey: 'userId.pubcid', source: 'pubcid.org'}, - {type: 17, bidKey: 'userId.uid2.id', source: 'uidapi.com'} + { type: 6, bidKey: 'userId.imuid', source: 'intimatemerger.com' }, + { type: 8, bidKey: 'userId.id5id.uid', source: 'id5-sync.com' }, + { type: 9, bidKey: 'userId.tdid', source: 'adserver.org' }, + { type: 10, bidKey: 'userId.novatiq.snowflake', source: 'novatiq.com' }, + { type: 12, bidKey: 'userId.dacId.id', source: 'dac.co.jp' }, + { type: 13, bidKey: 'userId.idl_env', source: 'liveramp.com' }, + { type: 14, bidKey: 'userId.criteoId', source: 'criteo.com' }, + { type: 15, bidKey: 'userId.pubcid', source: 'pubcid.org' }, + { type: 17, bidKey: 'userId.uid2.id', source: 'uidapi.com' } ]; function createCBT() { diff --git a/modules/mileBidAdapter.md b/modules/mileBidAdapter.md new file mode 100644 index 00000000000..0124c5f4327 --- /dev/null +++ b/modules/mileBidAdapter.md @@ -0,0 +1,72 @@ +# Overview + +``` +Module Name: Mile Bid Adapter +Module Type: Bidder Adapter +Maintainer: tech@mile.tech +``` + +# Description + +This bidder adapter connects to Mile demand sources. + +# Bid Params + +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------------------|------------------|--------| +| `placementId` | required | The placement ID for the ad unit | `'12345'` | string | +| `siteId` | required | The site ID for the publisher | `'site123'` | string | +| `publisherId` | required | The publisher ID | `'pub456'` | string | + +# Example Configuration + +```javascript +var adUnits = [{ + code: 'test-banner', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'mile', + params: { + placementId: 'test-placement', + siteId: 'test-site', + publisherId: 'test-pub' + } + }] +}]; +``` + +# User Sync Configuration + +To enable user syncing, configure Prebid.js with: + +```javascript +pbjs.setConfig({ + userSync: { + iframeEnabled: true, // Enable iframe syncs + filterSettings: { + iframe: { + bidders: ['mile'], + filter: 'include' + } + } + } +}); +``` + +# Test Parameters + +```javascript +{ + bidder: 'mile', + params: { + placementId: 'test-placement', + siteId: 'test-site', + publisherId: 'test-publisher-id' + } +} +``` + diff --git a/modules/mileBidAdapter.ts b/modules/mileBidAdapter.ts new file mode 100644 index 00000000000..7fb1def9a19 --- /dev/null +++ b/modules/mileBidAdapter.ts @@ -0,0 +1,428 @@ +import { type BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { deepAccess, deepSetValue, generateUUID, logInfo, logError } from '../src/utils.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { ajax } from '../src/ajax.js'; + +/** + * Mile Bid Adapter + * + * This adapter handles: + * 1. User syncs by sending requests to the prebid server cookie sync endpoint + * 2. Bid requests by parsing necessary parameters from the prebid auction + */ + +const BIDDER_CODE = 'mile'; + +const MILE_BIDDER_HOST = 'https://pbs.atmtd.com'; +const ENDPOINT_URL = `${MILE_BIDDER_HOST}/mile/v1/request`; +const USER_SYNC_ENDPOINT = `https://scripts.atmtd.com/user-sync/load-cookie.html`; + +const MILE_ANALYTICS_ENDPOINT = `https://e01.atmtd.com/bidanalytics-event/json`; + +type MileBidParams = { + placementId: string; + siteId: string; + publisherId: string; +}; + +declare module '../src/adUnits' { + interface BidderParams { + [BIDDER_CODE]: MileBidParams; + } +} + +export let siteIdTracker : string | undefined; +export let publisherIdTracker : string | undefined; + +export function getLowestFloorPrice(bid) { + let floorPrice: number; + + if (typeof bid.getFloor === 'function') { + let sizes = [] + // Get floor prices for each banner size in the bid request + if (deepAccess(bid, 'mediaTypes.banner.sizes')) { + sizes = deepAccess(bid, 'mediaTypes.banner.sizes') + } else if (bid.sizes) { + sizes = bid.sizes + } + + sizes.forEach((size: string | number[]) => { + const [w, h] = typeof size === 'string' ? size.split('x') : size as number[]; + const floor = bid.getFloor({ currency: 'USD', mediaType: '*', size: [Number(w), Number(h)] }); + if (floor && floor.floor) { + if (floorPrice === undefined) { + floorPrice = floor.floor; + } else { + floorPrice = Math.min(floorPrice, floor.floor); + } + } + }); + } else { + floorPrice = 0 + } + + return floorPrice +} + +export const spec: BidderSpec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER], + isBidRequestValid: function (bid) { + const params = bid.params; + + if (!params?.placementId) { + logError(`${BIDDER_CODE}: Missing required param: placementId`); + return false; + } + + if (!params?.siteId) { + logError(`${BIDDER_CODE}: Missing required param: siteId`); + return false; + } + + if (!params?.publisherId) { + logError(`${BIDDER_CODE}: Missing required param: publisherId`); + return false; + } + + if (siteIdTracker === undefined) { + siteIdTracker = params.siteId; + } else if (siteIdTracker !== params.siteId) { + logError(`${BIDDER_CODE}: Site ID mismatch: ${siteIdTracker} !== ${params.siteId}`); + return false; + } + + if (publisherIdTracker === undefined) { + publisherIdTracker = params.publisherId; + } else if (publisherIdTracker !== params.publisherId) { + logError(`${BIDDER_CODE}: Publisher ID mismatch: ${publisherIdTracker} !== ${params.publisherId}`); + return false; + } + + return true; + }, + + /** + * Make a server request from the list of BidRequests. + * Builds an OpenRTB 2.5 compliant bid request. + * + * @param validBidRequests - An array of valid bids + * @param bidderRequest - The master bidder request object + * @returns ServerRequest info describing the request to the server + */ + buildRequests: function (validBidRequests, bidderRequest) { + logInfo(`${BIDDER_CODE}: Building batched request for ${validBidRequests.length} bids`); + + // Build imp[] array - one impression object per bid request + const imps = validBidRequests.map((bid) => { + const sizes = deepAccess(bid, 'mediaTypes.banner.sizes') || []; + const floorPrice = getLowestFloorPrice(bid); + + const imp: any = { + id: bid.bidId, + tagid: bid.params.placementId, + secure: 1, + banner: { + format: sizes.map((size: number[]) => ({ + w: size[0], + h: size[1], + })) + }, + ext: { + adUnitCode: bid.adUnitCode, + placementId: bid.params.placementId, + gpid: deepAccess(bid, 'ortb2Imp.ext.gpid') || deepAccess(bid, 'ortb2Imp.ext.data.pbadslot'), + }, + }; + + // Add bidfloor if available + if (floorPrice > 0) { + imp.bidfloor = floorPrice; + imp.bidfloorcur = 'USD'; + } + + return imp; + }); + + // Build the OpenRTB 2.5 BidRequest object + const openRtbRequest: any = { + id: bidderRequest.bidderRequestId || generateUUID(), + imp: imps, + tmax: bidderRequest.timeout, + cur: ['USD'], + site: { + id: siteIdTracker, + page: deepAccess(bidderRequest, 'refererInfo.page') || '', + domain: deepAccess(bidderRequest, 'refererInfo.domain') || '', + ref: deepAccess(bidderRequest, 'refererInfo.ref') || '', + publisher: { + id: publisherIdTracker, + }, + }, + user: {}, + // Device object + device: { + ua: navigator.userAgent, + language: navigator.language?.split('-')[0] || 'en', + dnt: getDNT() ? 1 : 0, + w: window.screen?.width, + h: window.screen?.height, + }, + + // Source object with supply chain + source: { + tid: deepAccess(bidderRequest, 'ortb2.source.tid') + }, + }; + + // Add schain if available + const schain = deepAccess(validBidRequests, '0.ortb2.source.ext.schain'); + if (schain) { + deepSetValue(openRtbRequest, 'source.ext.schain', schain); + } + + // User object + const eids = deepAccess(validBidRequests, '0.userIdAsEids'); + if (eids && eids.length) { + deepSetValue(openRtbRequest, 'user.ext.eids', eids); + } + + // Regs object for privacy/consent + const regs: any = { ext: {} }; + + // GDPR + if (bidderRequest.gdprConsent) { + regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + deepSetValue(openRtbRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString || ''); + } + + // US Privacy (CCPA) + if (bidderRequest.uspConsent) { + regs.ext.us_privacy = bidderRequest.uspConsent; + } + + // GPP + if (bidderRequest.gppConsent) { + regs.gpp = bidderRequest.gppConsent.gppString || ''; + regs.gpp_sid = bidderRequest.gppConsent.applicableSections || []; + } + + if (Object.keys(regs.ext).length > 0 || regs.gpp) { + openRtbRequest.regs = regs; + } + + // Merge any first-party data from ortb2 + if (bidderRequest.ortb2) { + if (bidderRequest.ortb2.site) { + openRtbRequest.site = { ...openRtbRequest.site, ...bidderRequest.ortb2.site }; + // Preserve publisher ID + openRtbRequest.site.publisher = { id: publisherIdTracker, ...bidderRequest.ortb2.site.publisher }; + } + if (bidderRequest.ortb2.user) { + openRtbRequest.user = { ...openRtbRequest.user, ...bidderRequest.ortb2.user }; + } + if (bidderRequest.ortb2.device) { + openRtbRequest.device = { ...openRtbRequest.device, ...bidderRequest.ortb2.device }; + } + } + + // Add prebid adapter version info + deepSetValue(openRtbRequest, 'ext.prebid.channel', { + name: 'pbjs', + version: '$prebid.version$', + }); + + return { + method: 'POST', + url: ENDPOINT_URL, + data: openRtbRequest + }; + }, + + /** + * Unpack the OpenRTB 2.5 response from the server into a list of bids. + * + * @param serverResponse - A successful response from the server. + * @param request - The request that was sent to the server. + * @returns An array of bids which were nested inside the server. + */ + interpretResponse: function (serverResponse, request) { + const bidResponses: any[] = []; + + if (!serverResponse?.body) { + logInfo(`${BIDDER_CODE}: Empty server response`); + return bidResponses; + } + + const response = serverResponse.body; + const currency = response.cur || 'USD'; + + // OpenRTB 2.5 response format: seatbid[] contains bid[] + const seatbids = response.bids || []; + + seatbids.forEach((bid: any) => { + if (!bid || !bid.cpm) { + return; + } + + const bidResponse = { + requestId: bid.requestId, + cpm: parseFloat(bid.cpm), + width: parseInt(bid.width || bid.w, 10), + height: parseInt(bid.height || bid.h, 10), + creativeId: bid.creativeId || bid.crid || bid.id, + currency: currency, + netRevenue: true, + bidder: BIDDER_CODE, + ttl: bid.ttl || 300, + ad: bid.ad, + mediaType: BANNER, + meta: { + advertiserDomains: bid.adomain || [], + upstreamBidder: bid.upstreamBidder || '', + siteUID: deepAccess(response, 'site.id') || '', + publisherID: deepAccess(response, 'site.publisher.id') || '', + page: deepAccess(response, 'site.page') || '', + domain: deepAccess(response, 'site.domain') || '', + } + }; + + // Handle nurl (win notice URL) if present + if (bid.nurl) { + (bidResponse as any).nurl = bid.nurl; + } + + // Handle burl (billing URL) if present + if (bid.burl) { + (bidResponse as any).burl = bid.burl; + } + + bidResponses.push(bidResponse); + }); + + return bidResponses; + }, + + /** + * Register user sync pixels or iframes to be dropped after the auction. + * + * @param syncOptions - Which sync types are allowed (iframe, image/pixel) + * @param serverResponses - Array of server responses from the auction + * @param gdprConsent - GDPR consent data + * @param uspConsent - US Privacy consent string + * @param gppConsent - GPP consent data + * @returns Array of user sync objects to be executed + */ + getUserSyncs: function ( + syncOptions, + serverResponses, + gdprConsent, + uspConsent, + gppConsent + ) { + logInfo(`${BIDDER_CODE}: getUserSyncs called`, { + iframeEnabled: syncOptions.iframeEnabled + }); + + const syncs = []; + + // Build query parameters for consent + const queryParams: string[] = []; + + // GDPR consent + if (gdprConsent) { + queryParams.push(`gdpr=${gdprConsent.gdprApplies ? 1 : 0}`); + queryParams.push(`gdpr_consent=${encodeURIComponent(gdprConsent.consentString || '')}`); + } + + // US Privacy / CCPA + if (uspConsent) { + queryParams.push(`us_privacy=${encodeURIComponent(uspConsent)}`); + } + + // GPP consent + if (gppConsent?.gppString) { + queryParams.push(`gpp=${encodeURIComponent(gppConsent.gppString)}`); + if (gppConsent.applicableSections?.length) { + queryParams.push(`gpp_sid=${encodeURIComponent(gppConsent.applicableSections.join(','))}`); + } + } + + const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : ''; + + if (syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe' as const, + url: `${USER_SYNC_ENDPOINT}${queryString}`, + }); + } + + return syncs; + }, + + /** + * Called when a bid from this adapter wins the auction. + * Sends an XHR POST request to the bid's nurl (win notification URL). + * + * @param bid - The winning bid object + */ + onBidWon: function (bid) { + logInfo(`${BIDDER_CODE}: Bid won`, bid); + + const winNotificationData = { + adUnitCode: bid.adUnitCode, + metaData: { + impressionID: [bid.requestId], + }, + ua: navigator.userAgent, + timestamp: Date.now(), + winningSize: `${bid.width}x${bid.height}`, + cpm: bid.cpm, + eventType: 'mile-bidder-win-notify', + winningBidder: deepAccess(bid, 'meta.upstreamBidder') || '', + siteUID: deepAccess(bid, 'meta.siteUID') || '', + yetiPublisherID: deepAccess(bid, 'meta.publisherID') || '', + page: deepAccess(bid, 'meta.page') || '', + site: deepAccess(bid, 'meta.domain') || '', + } + + ajax(MILE_ANALYTICS_ENDPOINT, null, JSON.stringify([winNotificationData]), { method: 'POST' }); + + // @ts-expect-error - bid.nurl is not defined + if (bid.nurl) ajax(bid.nurl, null, null, { method: 'GET' }); + }, + + /** + * Called when bid requests timeout. + * Sends analytics notification for timed out bids. + * + * @param timeoutData - Array of bid requests that timed out + */ + onTimeout: function (timeoutData) { + logInfo(`${BIDDER_CODE}: Timeout for ${timeoutData.length} bid(s)`, timeoutData); + + if (timeoutData.length === 0) return; + + const timedOutBids = []; + + timeoutData.forEach((bid) => { + const timeoutNotificationData = { + adUnitCode: bid.adUnitCode, + metaData: { + impressionID: [bid.bidId], + configuredTimeout: [bid.timeout.toString()], + }, + ua: navigator.userAgent, + timestamp: Date.now(), + eventType: 'mile-bidder-timeout' + }; + + timedOutBids.push(timeoutNotificationData); + }); + + ajax(MILE_ANALYTICS_ENDPOINT, null, JSON.stringify(timedOutBids), { method: 'POST' }); + }, +}; + +registerBidder(spec); diff --git a/modules/minutemediaBidAdapter.js b/modules/minutemediaBidAdapter.js index d5aae8a84d0..3c009ff68ad 100644 --- a/modules/minutemediaBidAdapter.js +++ b/modules/minutemediaBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {makeBaseSpec} from '../libraries/riseUtils/index.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { makeBaseSpec } from '../libraries/riseUtils/index.js'; const BIDDER_CODE = 'minutemedia'; const BASE_URL = 'https://hb.minutemedia-prebid.com/'; diff --git a/modules/missenaBidAdapter.js b/modules/missenaBidAdapter.js index 573f20fb302..dba7a723693 100644 --- a/modules/missenaBidAdapter.js +++ b/modules/missenaBidAdapter.js @@ -157,6 +157,7 @@ export const spec = { serverResponses, gdprConsent = {}, uspConsent, + gppConsent, ) { if (!syncOptions.iframeEnabled || !this.msnaApiKey) { return []; @@ -172,6 +173,13 @@ export const spec = { if (uspConsent) { url.searchParams.append('us_privacy', uspConsent); } + if (gppConsent?.gppString) { + url.searchParams.append('gpp', gppConsent.gppString); + url.searchParams.append( + 'gpp_sid', + (gppConsent.applicableSections || []).join(','), + ); + } return [{ type: 'iframe', url: url.href }]; }, diff --git a/modules/mobianRtdProvider.md b/modules/mobianRtdProvider.md index ccfc43e3aab..dee9cc12773 100644 --- a/modules/mobianRtdProvider.md +++ b/modules/mobianRtdProvider.md @@ -160,6 +160,36 @@ p1 = Advertisers (via Campaign IDs) should target these personas *AP Values is in the early stages of testing and is subject to change. +------------------ + +Additional Results Fields (API response) + +The fields below are present in the Mobian Contextual API `results` schema and are useful for downstream interpretation of content maturity and taxonomy. + +mobianMpaaRating: + +Type: integer | null + +Description: MPAA-style maturity rating score represented as an integer value in the API response. + +Behavior when unavailable: omitted when null. + +mobianEsrbRating: + +Type: integer | null + +Description: ESRB-style maturity rating score represented as an integer value in the API response. + +Behavior when unavailable: omitted when null. + +mobianContentTaxonomy: + +Type: string[] + +Description: IAB content taxonomy categories (broad topic buckets such as "News" or "Health"). + +Behavior when unavailable: may be returned as an empty array. + ## GAM Targeting: On each page load, the Mobian RTD module finds each ad slot on the page and performs the following function: diff --git a/modules/mobilefuseBidAdapter.js b/modules/mobilefuseBidAdapter.js index d92d03672a9..c84db034bd3 100644 --- a/modules/mobilefuseBidAdapter.js +++ b/modules/mobilefuseBidAdapter.js @@ -1,8 +1,8 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {deepAccess, deepSetValue} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { deepAccess, deepSetValue } from '../src/utils.js'; import { config } from '../src/config.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { userSync } from '../src/userSync.js'; const ADAPTER_VERSION = '1.0.0'; @@ -76,7 +76,7 @@ function buildRequests(validBidRequests, bidderRequest) { return { method: 'POST', url: ENDPOINT_URL, - data: converter.toORTB({validBidRequests, bidderRequest}), + data: converter.toORTB({ validBidRequests, bidderRequest }), }; } @@ -106,7 +106,7 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gpp const querystring = params.length ? `?${params.join('&')}` : ''; - return [{type: 'iframe', url: `${SYNC_URL}${querystring}`}]; + return [{ type: 'iframe', url: `${SYNC_URL}${querystring}` }]; } const pixels = []; @@ -114,7 +114,7 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gpp serverResponses.forEach(response => { if (response.body.ext && response.body.ext.syncs) { response.body.ext.syncs.forEach(url => { - pixels.push({type: 'image', url: url}); + pixels.push({ type: 'image', url: url }); }); } }); diff --git a/modules/mobkoiAnalyticsAdapter.js b/modules/mobkoiAnalyticsAdapter.js index a8d373e3a3b..4d35149bf01 100644 --- a/modules/mobkoiAnalyticsAdapter.js +++ b/modules/mobkoiAnalyticsAdapter.js @@ -76,6 +76,7 @@ export class LocalContext { _impressionPayloadCache = { // [impid]: { ... } }; + /** * The payload that is common to all bid contexts. The payload will be * submitted to the server along with the debug events. @@ -87,6 +88,7 @@ export class LocalContext { return this._impressionPayloadCache[impid] || {}; } + /** * Update the payload for all impressions. The new values will be merged to * the existing payload. @@ -253,7 +255,7 @@ export class LocalContext { * @param {*} params.subPayloads Objects containing additional data that are * obtain from to the Prebid events indexed by SUB_PAYLOAD_TYPES. */ - pushEventToAllBidContexts({eventType, level, timestamp, note, subPayloads}) { + pushEventToAllBidContexts({ eventType, level, timestamp, note, subPayloads }) { // Create one event for each impression ID _each(this.getAllBidderRequestImpIds(), impid => { const eventClone = new Event({ @@ -466,7 +468,7 @@ function pickKeyFields(objType, eventArgs) { } } -const mobkoiAnalytics = Object.assign(adapter({analyticsType}), { +const mobkoiAnalytics = Object.assign(adapter({ analyticsType }), { localContext: new LocalContext(), async track({ eventType, @@ -597,7 +599,7 @@ const mobkoiAnalytics = Object.assign(adapter({analyticsType}), { case AD_RENDER_FAILED: { utils.logTrackEvent(eventType, prebidEventArgs); const argsType = utils.determineObjType(prebidEventArgs); - const {bid: prebidBid} = prebidEventArgs; + const { bid: prebidBid } = prebidEventArgs; const bidContext = this.localContext.retrieveBidContext(prebidBid); bidContext.pushEvent({ eventInstance: new Event({ @@ -775,6 +777,7 @@ class BidContext { get subPayloads() { return this._subPayloads; } + /** * To avoid overriding the subPayloads object, we merge the new values to the * existing subPayloads object. Identity fields will automatically added to the @@ -868,7 +871,7 @@ class BidContext { * @param {Event} params.eventInstance - DebugEvent object. If it does not contain the same impid as the BidContext, the event will be ignored. * @param {Object|null} params.subPayloads - Object containing various payloads obtained from the Prebid Event args. The payloads will be merged into the existing subPayloads. */ - pushEvent({eventInstance, subPayloads}) { + pushEvent({ eventInstance, subPayloads }) { if (!(eventInstance instanceof Event)) { throw new Error('bugEvent must be an instance of DebugEvent'); } @@ -919,7 +922,7 @@ class Event { */ timestamp = null; - constructor({eventType, impid, publisherId, level, timestamp, note = undefined}) { + constructor({ eventType, impid, publisherId, level, timestamp, note = undefined }) { if (!eventType) { throw new Error('eventType is required'); } diff --git a/modules/mobkoiBidAdapter.js b/modules/mobkoiBidAdapter.js index ff5be0293ac..3ec4861ee4b 100644 --- a/modules/mobkoiBidAdapter.js +++ b/modules/mobkoiBidAdapter.js @@ -91,7 +91,7 @@ export const spec = { interpretResponse(serverResponse, customBidRequest) { if (!serverResponse.body) return []; - const responseBody = {...serverResponse.body, seatbid: serverResponse.body.seatbid}; + const responseBody = { ...serverResponse.body, seatbid: serverResponse.body.seatbid }; const prebidBidResponse = converter.fromORTB({ request: customBidRequest.data, response: responseBody, @@ -182,7 +182,7 @@ export const utils = { 'Failed to obtain placement ID from the given object. ' + `Please set it via the "${paramPath}" field in the bid configuration.\n` + 'Given object:\n' + - JSON.stringify({functionParam: prebidBidRequestOrOrtbBidRequest}, null, 3) + JSON.stringify({ functionParam: prebidBidRequestOrOrtbBidRequest }, null, 3) ); } diff --git a/modules/msftBidAdapter.js b/modules/msftBidAdapter.js index 6155b91e778..8cc396a9417 100644 --- a/modules/msftBidAdapter.js +++ b/modules/msftBidAdapter.js @@ -376,7 +376,7 @@ export const spec = { return [{ type: "iframe", url: "https://acdn.adnxs.com/dmp/async_usersync.html", - }, ]; + },]; } if (syncOptions.pixelEnabled) { diff --git a/modules/msftBidAdapter.md b/modules/msftBidAdapter.md index df5be0a1fb6..3d5c9f4ff5b 100644 --- a/modules/msftBidAdapter.md +++ b/modules/msftBidAdapter.md @@ -10,7 +10,7 @@ Maintainer: prebid@microsoft.com The Microsoft Bid Adapter connects to Microsoft's advertising exchange for bids. This adapter supports banner, video (instream and outstream), and native ad formats using OpenRTB 2.5 standards. -The Microsoft adapter requires setup and approval from the Microsoft Advertising team. Please reach out to your account team for more information. +If you are transitioning from the AppNexus bid adapter and you have any questions or concerns, please reach out to your account team for assistance. # Migration from AppNexus Bid Adapter diff --git a/modules/multibid/index.ts b/modules/multibid/index.ts index d7f6b0cbb38..7b1f137ad3a 100644 --- a/modules/multibid/index.ts +++ b/modules/multibid/index.ts @@ -3,18 +3,18 @@ * @module modules/multibid */ -import {config} from '../../src/config.js'; -import {setupBeforeHookFnOnce, getHook} from '../../src/hook.js'; +import { config } from '../../src/config.js'; +import { setupBeforeHookFnOnce, getHook } from '../../src/hook.js'; import { logWarn, deepAccess, getUniqueIdentifierStr, deepSetValue, groupBy } from '../../src/utils.js'; import * as events from '../../src/events.js'; import { EVENTS } from '../../src/constants.js'; -import {addBidderRequests} from '../../src/auction.js'; -import {getHighestCpmBidsFromBidPool, sortByDealAndPriceBucketOrCpm} from '../../src/targeting.js'; -import {PBS, registerOrtbProcessor, REQUEST} from '../../src/pbjsORTB.js'; -import {timedBidResponseHook} from '../../src/utils/perfMetrics.js'; -import type {BidderCode} from "../../src/types/common.d.ts"; +import { addBidderRequests } from '../../src/auction.js'; +import { getHighestCpmBidsFromBidPool, sortByDealAndPriceBucketOrCpm } from '../../src/targeting.js'; +import { PBS, registerOrtbProcessor, REQUEST } from '../../src/pbjsORTB.js'; +import { timedBidResponseHook } from '../../src/utils/perfMetrics.js'; +import type { BidderCode } from "../../src/types/common.d.ts"; const MODULE_NAME = 'multibid'; let hasMultibid = false; @@ -102,7 +102,7 @@ export function validateMultibid(conf) { return entry; }); - if (!check) config.setConfig({multibid: duplicate}); + if (!check) config.setConfig({ multibid: duplicate }); return check; } @@ -175,9 +175,9 @@ export const addBidResponseHook = timedBidResponseHook('multibid', function addB logWarn(`Filtering multibid received from bidder ${bid.bidderCode}: ` + ((multibidUnits[adUnitCode][bid.bidderCode].maxReached) ? `Maximum bid limit reached for ad unit code ${adUnitCode}` : 'Bid cpm under floors value.')); } } else { - if (deepAccess(bid, 'floorData.floorValue')) deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], {floor: deepAccess(bid, 'floorData.floorValue')}); + if (deepAccess(bid, 'floorData.floorValue')) deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], { floor: deepAccess(bid, 'floorData.floorValue') }); - deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], {ads: [bid]}); + deepSetValue(multibidUnits, [adUnitCode, bid.bidderCode], { ads: [bid] }); if (multibidUnits[adUnitCode][bid.bidderCode].ads.length === multiConfig[bid.bidderCode].maxbids) multibidUnits[adUnitCode][bid.bidderCode].maxReached = true; fn.call(this, adUnitCode, bid, reject); @@ -291,4 +291,4 @@ export function setOrtbExtPrebidMultibid(ortbRequest) { } } -registerOrtbProcessor({type: REQUEST, name: 'extPrebidMultibid', fn: setOrtbExtPrebidMultibid, dialects: [PBS]}); +registerOrtbProcessor({ type: REQUEST, name: 'extPrebidMultibid', fn: setOrtbExtPrebidMultibid, dialects: [PBS] }); diff --git a/modules/mwOpenLinkIdSystem.js b/modules/mwOpenLinkIdSystem.js index f638f955fd0..af0a1701e23 100644 --- a/modules/mwOpenLinkIdSystem.js +++ b/modules/mwOpenLinkIdSystem.js @@ -8,8 +8,8 @@ import { timestamp, logError, deepClone, generateUUID, isPlainObject } from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -22,7 +22,7 @@ const openLinkID = { cookie_expiration: (86400 * 1000 * 365 * 1) // 1 year } -const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: openLinkID.name}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: openLinkID.name }); function getExpirationDate() { return (new Date(timestamp() + openLinkID.cookie_expiration)).toGMTString(); @@ -103,7 +103,7 @@ function register(configParams, olid) { function setID(configParams) { if (!isValidConfig(configParams)) return undefined; const mwOlId = readCookie(); - const newMwOlId = mwOlId ? deepClone(mwOlId) : {eid: generateUUID()}; + const newMwOlId = mwOlId ? deepClone(mwOlId) : { eid: generateUUID() }; writeCookie(newMwOlId); register(configParams, newMwOlId.eid); return { diff --git a/modules/my6senseBidAdapter.js b/modules/my6senseBidAdapter.js index 9823783a557..93c3bb75e2a 100644 --- a/modules/my6senseBidAdapter.js +++ b/modules/my6senseBidAdapter.js @@ -1,5 +1,5 @@ import { BANNER, NATIVE } from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const BIDDER_CODE = 'my6sense'; diff --git a/modules/nativeRendering.js b/modules/nativeRendering.js index b3a382a0483..e90bf4e42a9 100644 --- a/modules/nativeRendering.js +++ b/modules/nativeRendering.js @@ -1,9 +1,9 @@ -import {getRenderingData} from '../src/adRendering.js'; -import {getNativeRenderingData, isNativeResponse} from '../src/native.js'; -import {auctionManager} from '../src/auctionManager.js'; +import { getRenderingData } from '../src/adRendering.js'; +import { getNativeRenderingData, isNativeResponse } from '../src/native.js'; +import { auctionManager } from '../src/auctionManager.js'; // eslint-disable-next-line prebid/validate-imports -import {RENDERER} from '../creative-renderers/native.js'; // autogenerated during precompilation -import {getCreativeRendererSource} from '../src/creativeRenderers.js'; +import { RENDERER } from '../creative-renderers/native.js'; // autogenerated during precompilation +import { getCreativeRendererSource } from '../src/creativeRenderers.js'; function getRenderingDataHook(next, bidResponse, options) { if (isNativeResponse(bidResponse)) { diff --git a/modules/nativoBidAdapter.js b/modules/nativoBidAdapter.js index 3a981d65812..1fd6a8fca1d 100644 --- a/modules/nativoBidAdapter.js +++ b/modules/nativoBidAdapter.js @@ -542,6 +542,7 @@ export class BidRequestDataSource { constructor() { this.type = 'BidRequestDataSource' } + processBidRequestData(bidRequest, bidderRequest) {} getRequestQueryString() { return '' diff --git a/modules/naveggIdSystem.js b/modules/naveggIdSystem.js index 6f1964b11df..feb853cbabf 100644 --- a/modules/naveggIdSystem.js +++ b/modules/naveggIdSystem.js @@ -20,7 +20,7 @@ const OLD_NAVEGG_ID = 'nid'; const NAVEGG_ID = 'nvggid'; const BASE_URL = 'https://id.navegg.com/uid/'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function getIdFromAPI() { const resp = function (callback) { @@ -50,7 +50,7 @@ function getIdFromAPI() { const fallbackValue = getNaveggIdFromLocalStorage() || getOldCookie(); callback(fallbackValue); }, - {method: 'GET', withCredentials: false}); + { method: 'GET', withCredentials: false }); }; return resp; } @@ -115,7 +115,7 @@ export const naveggIdSubmodule = { */ getId(config, consentData) { const resp = getIdFromAPI() - return {callback: resp} + return { callback: resp } }, eids: { 'naveggId': { diff --git a/modules/netIdSystem.js b/modules/netIdSystem.js index 4482013b46c..bb5a0421ae9 100644 --- a/modules/netIdSystem.js +++ b/modules/netIdSystem.js @@ -5,7 +5,7 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; +import { submodule } from '../src/hook.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule diff --git a/modules/neuwoRtdProvider.js b/modules/neuwoRtdProvider.js index 3255547aa47..8371c20fb88 100644 --- a/modules/neuwoRtdProvider.js +++ b/modules/neuwoRtdProvider.js @@ -1,5 +1,6 @@ /** * @module neuwoRtdProvider + * @version 2.2.6 * @author Grzegorz Malisz * @see {project-root-directory}/integrationExamples/gpt/neuwoRtdProvider_example.html for an example/testing page. * @see {project-root-directory}/test/spec/modules/neuwoRtdProvider_spec.js for unit tests. @@ -7,8 +8,10 @@ * This module is a Prebid.js Real-Time Data (RTD) provider that integrates with the Neuwo API. * * It fetches contextual marketing categories (IAB content and audience) for the current page from the Neuwo API. - * The retrieved data is then injected into the bid request as OpenRTB (ORTB2)`site.content.data` + * The retrieved data is then injected into the bid request as OpenRTB (ORTB2) `site.content.data` * and `user.data` fragments, making it available for bidders to use in their decisioning process. + * Additionally, when enabled, the module populates OpenRTB 2.5 category fields (`ortb2.site.cat`, + * `ortb2.site.sectioncat`, `ortb2.site.pagecat`, `ortb2.site.content.cat`) with IAB Content Taxonomy 1.0 segments. * * @see {@link https://docs.prebid.org/dev-docs/add-rtd-submodule.html} for more information on development of Prebid.js RTD modules. * @see {@link https://docs.prebid.org/features/firstPartyData.html} for more information on Prebid.js First Party Data. @@ -18,24 +21,40 @@ import { ajax } from "../src/ajax.js"; import { submodule } from "../src/hook.js"; import { getRefererInfo } from "../src/refererDetection.js"; -import { deepSetValue, logError, logInfo, mergeDeep } from "../src/utils.js"; +import { + deepSetValue, + logError, + logInfo, + logWarn, + mergeDeep, +} from "../src/utils.js"; const MODULE_NAME = "NeuwoRTDModule"; +const MODULE_VERSION = "2.2.6"; export const DATA_PROVIDER = "www.neuwo.ai"; -// Cached API response to avoid redundant requests. -let globalCachedResponse; +// Default IAB Content Taxonomy version +const DEFAULT_IAB_CONTENT_TAXONOMY_VERSION = "2.2"; + +// Maximum number of cached API responses to keep. Oldest entries are evicted when exceeded. +const MAX_CACHE_ENTRIES = 10; +// Cached API responses keyed by full API URL to avoid redundant requests. +let cachedResponses = {}; +// In-flight request promises keyed by full API URL to prevent duplicate API calls during the same request cycle. +let pendingRequests = {}; /** - * Clears the cached API response. Primarily used for testing. + * Clears the cached API responses and pending requests. Primarily used for testing. * @private */ export function clearCache() { - globalCachedResponse = undefined; + cachedResponses = {}; + pendingRequests = {}; } // Maps the IAB Content Taxonomy version string to the corresponding segtax ID. // Based on https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/main/AdCOM%20v1.0%20FINAL.md#list--category-taxonomies- +// prettier-ignore const IAB_CONTENT_TAXONOMY_MAP = { "1.0": 1, "2.0": 2, @@ -53,14 +72,14 @@ const IAB_CONTENT_TAXONOMY_MAP = { * @returns {boolean} `true` if the module is configured correctly, otherwise `false`. */ function init(config, userConsent) { - logInfo(MODULE_NAME, "init:", config, userConsent); + logInfo(MODULE_NAME, "init():", "Version " + MODULE_VERSION, config, userConsent); const params = config?.params || {}; if (!params.neuwoApiUrl) { - logError(MODULE_NAME, "init:", "Missing Neuwo Edge API Endpoint URL"); + logError(MODULE_NAME, "init():", "Missing Neuwo Edge API Endpoint URL"); return false; } if (!params.neuwoApiToken) { - logError(MODULE_NAME, "init:", "Missing Neuwo API Token missing"); + logError(MODULE_NAME, "init():", "Missing Neuwo API Token"); return false; } return true; @@ -69,6 +88,9 @@ function init(config, userConsent) { /** * Fetches contextual data from the Neuwo API and enriches the bid request object with IAB categories. * Uses cached response if available to avoid redundant API calls. + * Automatically detects API capabilities from the endpoint URL format: + * - URLs containing "/v1/iab" use GET requests with server-side filtering + * - Other URLs use GET requests with client-side filtering (legacy support) * * @param {Object} reqBidsConfigObj The bid request configuration object. * @param {function} callback The callback function to continue the auction. @@ -77,70 +99,272 @@ function init(config, userConsent) { * @param {string} config.params.neuwoApiUrl The Neuwo API endpoint URL. * @param {string} config.params.neuwoApiToken The Neuwo API authentication token. * @param {string} [config.params.websiteToAnalyseUrl] Optional URL to analyze instead of current page. - * @param {string} [config.params.iabContentTaxonomyVersion] IAB content taxonomy version (default: "3.0"). - * @param {boolean} [config.params.enableCache=true] If true, caches API responses to avoid redundant requests (default: true). + * @param {string} [config.params.iabContentTaxonomyVersion="2.2"] IAB Content Taxonomy version. + * @param {boolean} [config.params.enableCache=true] If true, caches API responses to avoid redundant requests. + * @param {boolean} [config.params.enableOrtb25Fields=true] If true, populates OpenRTB 2.5 category fields (site.cat, site.sectioncat, site.pagecat, site.content.cat) with IAB Content Taxonomy 1.0 segments. * @param {boolean} [config.params.stripAllQueryParams] If true, strips all query parameters from the URL. * @param {string[]} [config.params.stripQueryParamsForDomains] List of domains for which to strip all query params. * @param {string[]} [config.params.stripQueryParams] List of specific query parameter names to strip. * @param {boolean} [config.params.stripFragments] If true, strips URL fragments (hash). + * @param {Object} [config.params.iabTaxonomyFilters] Per-tier filtering configuration for IAB Taxonomies. * @param {Object} userConsent The user consent object. */ -export function getBidRequestData(reqBidsConfigObj, callback, config, userConsent) { - logInfo(MODULE_NAME, "getBidRequestData:", "starting getBidRequestData", config); +export function getBidRequestData( + reqBidsConfigObj, + callback, + config, + userConsent +) { + logInfo( + MODULE_NAME, + "getBidRequestData():", + "starting getBidRequestData", + config + ); const { websiteToAnalyseUrl, neuwoApiUrl, neuwoApiToken, - iabContentTaxonomyVersion, + iabContentTaxonomyVersion = DEFAULT_IAB_CONTENT_TAXONOMY_VERSION, enableCache = true, + enableOrtb25Fields = true, stripAllQueryParams, stripQueryParamsForDomains, stripQueryParams, stripFragments, + iabTaxonomyFilters, } = config.params; const rawUrl = websiteToAnalyseUrl || getRefererInfo().page; + if (!rawUrl) { + logError(MODULE_NAME, "getBidRequestData():", "No URL available to analyse"); + callback(); + return; + } const processedUrl = cleanUrl(rawUrl, { stripAllQueryParams, stripQueryParamsForDomains, stripQueryParams, - stripFragments + stripFragments, }); const pageUrl = encodeURIComponent(processedUrl); - // Adjusted for pages api.url?prefix=test (to add params with '&') as well as api.url (to add params with '?') - const joiner = neuwoApiUrl.indexOf("?") < 0 ? "?" : "&"; - const neuwoApiUrlFull = - neuwoApiUrl + joiner + ["token=" + neuwoApiToken, "url=" + pageUrl].join("&"); + const contentSegtax = + IAB_CONTENT_TAXONOMY_MAP[iabContentTaxonomyVersion] || + IAB_CONTENT_TAXONOMY_MAP[DEFAULT_IAB_CONTENT_TAXONOMY_VERSION]; - const success = (response) => { - logInfo(MODULE_NAME, "getBidRequestData:", "Neuwo API raw response:", response); - try { - const responseParsed = JSON.parse(response); + // Detect whether the endpoint supports multi-taxonomy responses and server-side filtering. + // Use URL pathname to avoid false positives when "/v1/iab" appears in query params. + let isIabEndpoint = false; + try { + isIabEndpoint = new URL(neuwoApiUrl).pathname.includes("/v1/iab"); + } catch (e) { + isIabEndpoint = neuwoApiUrl.split("?")[0].includes("/v1/iab"); + } - if (enableCache) { - globalCachedResponse = responseParsed; - } + // Warn if OpenRTB 2.5 feature enabled with legacy endpoint + if (enableOrtb25Fields && !isIabEndpoint) { + logWarn( + MODULE_NAME, + "getBidRequestData():", + "OpenRTB 2.5 category fields require the /v1/iab endpoint" + ); + } - injectIabCategories(responseParsed, reqBidsConfigObj, iabContentTaxonomyVersion); - } catch (ex) { - logError(MODULE_NAME, "getBidRequestData:", "Error while processing Neuwo API response", ex); + const joiner = neuwoApiUrl.indexOf("?") < 0 ? "?" : "&"; + const urlParams = [ + "token=" + neuwoApiToken, + "url=" + pageUrl, + "_neuwo_prod=PrebidModule", + ]; + + // Request both IAB Content Taxonomy (based on config) and IAB Audience Taxonomy (segtax 4) + if (isIabEndpoint) { + urlParams.push("iabVersions=" + contentSegtax); + urlParams.push("iabVersions=4"); // IAB Audience 1.1 + + // Request IAB 1.0 for OpenRTB 2.5 fields if feature enabled. + // Skip when contentSegtax is already 1 -- already requested above. + if (enableOrtb25Fields && contentSegtax !== 1) { + urlParams.push("iabVersions=1"); // IAB Content 1.0 } - callback(); - }; - const error = (err) => { - logError(MODULE_NAME, "getBidRequestData:", "AJAX error:", err); - callback(); - }; + // Add flattened filter parameters to URL for GET request + const filterParams = buildFilterQueryParams( + iabTaxonomyFilters, + contentSegtax, + enableOrtb25Fields + ); + if (filterParams.length > 0) { + urlParams.push(...filterParams); + } + } - if (enableCache && globalCachedResponse) { - logInfo(MODULE_NAME, "getBidRequestData:", "Using cached response:", globalCachedResponse); - injectIabCategories(globalCachedResponse, reqBidsConfigObj, iabContentTaxonomyVersion); + const neuwoApiUrlFull = neuwoApiUrl + joiner + urlParams.join("&"); + + // For /v1/iab endpoints the full URL already encodes all config (iabVersions, filters). + // For legacy endpoints the URL only carries token + page URL, so append config-dependent + // values to the cache key to prevent different configs sharing a response that was + // transformed/filtered for a different taxonomy version or filter set. + let cacheKey = neuwoApiUrlFull; + if (!isIabEndpoint) { + cacheKey += "&_segtax=" + contentSegtax; + if (iabTaxonomyFilters && Object.keys(iabTaxonomyFilters).length > 0) { + cacheKey += "&_filters=" + JSON.stringify(iabTaxonomyFilters); + } + } + + // Cache flow: cached response -> pending request -> new request + // Each caller gets their own callback invoked when data is ready. + // Keyed by cacheKey to ensure different parameters never share cached data. + if (enableCache && cachedResponses[cacheKey]) { + // Previous request succeeded - use cached response immediately + logInfo( + MODULE_NAME, + "getBidRequestData():", + "Cache System:", + "Using cached response for:", + cacheKey + ); + injectIabCategories( + cachedResponses[cacheKey], + reqBidsConfigObj, + iabContentTaxonomyVersion, + enableOrtb25Fields + ); callback(); + } else if (enableCache && pendingRequests[cacheKey]) { + // Another caller started a request with the same params - wait for it + logInfo( + MODULE_NAME, + "getBidRequestData():", + "Cache System:", + "Waiting for pending request for:", + cacheKey + ); + pendingRequests[cacheKey] + .then((responseParsed) => { + if (responseParsed) { + injectIabCategories( + responseParsed, + reqBidsConfigObj, + iabContentTaxonomyVersion, + enableOrtb25Fields + ); + } + }) + .finally(() => callback()); } else { - logInfo(MODULE_NAME, "getBidRequestData:", "Calling Neuwo API Endpoint: ", neuwoApiUrlFull); - ajax(neuwoApiUrlFull, { success, error }, null); + // First request or cache disabled - make the API call + logInfo( + MODULE_NAME, + "getBidRequestData():", + "Cache System:", + "Calling Neuwo API Endpoint:", + neuwoApiUrlFull + ); + + const requestPromise = new Promise((resolve) => { + ajax( + neuwoApiUrlFull, + { + success: (response) => { + logInfo( + MODULE_NAME, + "getBidRequestData():", + "success():", + "Neuwo API raw response:", + response + ); + + let responseParsed; + try { + responseParsed = JSON.parse(response); + } catch (ex) { + logError( + MODULE_NAME, + "getBidRequestData():", + "success():", + "Error parsing Neuwo API response JSON:", + ex + ); + resolve(null); + return; + } + + try { + if (!isIabEndpoint) { + // Apply per-tier filtering to V1 format + const filteredMarketingCategories = filterIabTaxonomies( + responseParsed.marketing_categories, + iabTaxonomyFilters + ); + + // Transform filtered V1 response to unified internal format + responseParsed = transformV1ResponseToV2( + { marketing_categories: filteredMarketingCategories }, + contentSegtax + ); + } + + // Cache response, evicting oldest entry if at capacity. + // Only cache valid responses so failed requests can be retried. + if ( + enableCache && + responseParsed && + typeof responseParsed === "object" + ) { + // Object.keys() preserves string insertion order in modern JS engines. + const keys = Object.keys(cachedResponses); + if (keys.length >= MAX_CACHE_ENTRIES) { + delete cachedResponses[keys[0]]; + } + cachedResponses[cacheKey] = responseParsed; + } + + injectIabCategories( + responseParsed, + reqBidsConfigObj, + iabContentTaxonomyVersion, + enableOrtb25Fields + ); + resolve(responseParsed); + } catch (ex) { + logError( + MODULE_NAME, + "getBidRequestData():", + "success():", + "Error processing Neuwo API response:", + ex + ); + resolve(null); + } + }, + error: (err) => { + logError( + MODULE_NAME, + "getBidRequestData():", + "error():", + "AJAX error:", + err + ); + resolve(null); + }, + } + ); + }); + + if (enableCache) { + // Store promise so concurrent callers with same params can wait on it + pendingRequests[cacheKey] = requestPromise; + // Clear after settling so failed requests can be retried + requestPromise.finally(() => { + delete pendingRequests[cacheKey]; + }); + } + + // Signal this caller's auction to proceed once request completes + requestPromise.finally(() => callback()); } } @@ -160,14 +384,23 @@ export function getBidRequestData(reqBidsConfigObj, callback, config, userConsen * @returns {string} The cleaned URL. */ export function cleanUrl(url, options = {}) { - const { stripAllQueryParams, stripQueryParamsForDomains, stripQueryParams, stripFragments } = options; + const { + stripAllQueryParams, + stripQueryParamsForDomains, + stripQueryParams, + stripFragments, + } = options; if (!url) { - logInfo(MODULE_NAME, "cleanUrl:", "Empty or null URL provided, returning as-is"); + logInfo( + MODULE_NAME, + "cleanUrl():", + "Empty or null URL provided, returning as-is" + ); return url; } - logInfo(MODULE_NAME, "cleanUrl:", "Input URL:", url, "Options:", options); + logInfo(MODULE_NAME, "cleanUrl():", "Input URL:", url, "Options:", options); try { const urlObj = new URL(url); @@ -175,21 +408,24 @@ export function cleanUrl(url, options = {}) { // Strip fragments if requested if (stripFragments === true) { urlObj.hash = ""; - logInfo(MODULE_NAME, "cleanUrl:", "Stripped fragment from URL"); + logInfo(MODULE_NAME, "cleanUrl():", "Stripped fragment from URL"); } // Option 1: Strip all query params unconditionally if (stripAllQueryParams === true) { urlObj.search = ""; const cleanedUrl = urlObj.toString(); - logInfo(MODULE_NAME, "cleanUrl:", "Output URL:", cleanedUrl); + logInfo(MODULE_NAME, "cleanUrl():", "Output URL:", cleanedUrl); return cleanedUrl; } // Option 2: Strip all query params for specific domains - if (Array.isArray(stripQueryParamsForDomains) && stripQueryParamsForDomains.length > 0) { + if ( + Array.isArray(stripQueryParamsForDomains) && + stripQueryParamsForDomains.length > 0 + ) { const hostname = urlObj.hostname; - const shouldStripForDomain = stripQueryParamsForDomains.some(domain => { + const shouldStripForDomain = stripQueryParamsForDomains.some((domain) => { // Support exact match or subdomain match return hostname === domain || hostname.endsWith("." + domain); }); @@ -197,7 +433,7 @@ export function cleanUrl(url, options = {}) { if (shouldStripForDomain) { urlObj.search = ""; const cleanedUrl = urlObj.toString(); - logInfo(MODULE_NAME, "cleanUrl:", "Output URL:", cleanedUrl); + logInfo(MODULE_NAME, "cleanUrl():", "Output URL:", cleanedUrl); return cleanedUrl; } } @@ -208,21 +444,25 @@ export function cleanUrl(url, options = {}) { // - "??" is treated as query parameter with key "?" and value "" if (Array.isArray(stripQueryParams) && stripQueryParams.length > 0) { const queryParams = urlObj.searchParams; - logInfo(MODULE_NAME, "cleanUrl:", `Query parameters to strip: ${stripQueryParams}`); - stripQueryParams.forEach(param => { + logInfo( + MODULE_NAME, + "cleanUrl():", + `Query parameters to strip: ${stripQueryParams}` + ); + stripQueryParams.forEach((param) => { queryParams.delete(param); }); urlObj.search = queryParams.toString(); const cleanedUrl = urlObj.toString(); - logInfo(MODULE_NAME, "cleanUrl:", "Output URL:", cleanedUrl); + logInfo(MODULE_NAME, "cleanUrl():", "Output URL:", cleanedUrl); return cleanedUrl; } const finalUrl = urlObj.toString(); - logInfo(MODULE_NAME, "cleanUrl:", "Output URL:", finalUrl); + logInfo(MODULE_NAME, "cleanUrl():", "Output URL:", finalUrl); return finalUrl; } catch (e) { - logError(MODULE_NAME, "cleanUrl:", "Error cleaning URL:", e); + logError(MODULE_NAME, "cleanUrl():", "Error cleaning URL:", e); return url; } } @@ -241,72 +481,435 @@ export function injectOrtbData(reqBidsConfigObj, path, data) { } /** - * Builds an IAB category data object for use in OpenRTB. + * Extracts all segment IDs from tier data into a flat array. + * Used for populating OpenRTB 2.5 category fields and building IAB data objects. + * + * @param {Object} tierData The tier data keyed by tier numbers (e.g., {"1": [{id: "IAB12"}], "2": [...]}). + * @returns {Array} Flat array of segment IDs (e.g., ["IAB12", "IAB12-3", "IAB12-5"]). + */ +export function extractCategoryIds(tierData) { + const ids = []; + + // Handle null, undefined, non-object, or array tierData + if (!tierData || typeof tierData !== "object" || Array.isArray(tierData)) { + return ids; + } + + // Process ALL tier keys present in tierData + Object.keys(tierData).forEach((tierKey) => { + const segments = tierData[tierKey]; + if (Array.isArray(segments)) { + segments.forEach((item) => { + if (item?.id) { + ids.push(item.id); + } + }); + } + }); + + return ids; +} + +/** + * Builds an IAB category data object for OpenRTB injection. + * Dynamically processes all tiers present in the response data. * - * @param {Object} marketingCategories Marketing Categories returned by Neuwo API. - * @param {string[]} tiers The tier keys to extract from marketingCategories. - * @param {number} segtax The IAB taxonomy version Id. - * @returns {Object} The constructed data object. + * @param {Object} tierData The tier data keyed by tier numbers (e.g., {"1": [...], "2": [...], "3": [...]}). + * @param {number} segtax The IAB Taxonomy segtax ID. + * @returns {Object} The OpenRTB data object with name, segment array, and ext.segtax. */ -export function buildIabData(marketingCategories, tiers, segtax) { - const data = { +export function buildIabData(tierData, segtax) { + const ids = extractCategoryIds(tierData); + return { name: DATA_PROVIDER, - segment: [], + segment: ids.map((id) => ({ id })), ext: { segtax }, }; +} + +/** + * v1 API specific + * Filters and limits a single tier's taxonomies based on relevance score and count. + * Used for client-side filtering with legacy endpoints. + * + * @param {Array} iabTaxonomies Array of IAB Taxonomy Segments objects with ID, label, and relevance. + * @param {Object} filter Filter configuration with optional threshold and limit properties. + * @returns {Array} Filtered and limited array of taxonomies, sorted by relevance (highest first). + */ +export function filterIabTaxonomyTier(iabTaxonomies, filter = {}) { + if (!Array.isArray(iabTaxonomies)) { + return []; + } + if (iabTaxonomies.length === 0) { + return iabTaxonomies; + } - tiers.forEach((tier) => { - const tierData = marketingCategories?.[tier]; + const { threshold, limit } = filter; + const hasThreshold = typeof threshold === "number" && threshold > 0; + const hasLimit = typeof limit === "number" && limit >= 0; + + // No effective filter configured -- return original order unchanged + if (!hasThreshold && !hasLimit) { + return iabTaxonomies; + } + + let filtered = [...iabTaxonomies]; // Create copy to avoid mutating original + + // Filter by minimum relevance score + if (hasThreshold) { + filtered = filtered.filter((item) => { + const relevance = parseFloat(item?.relevance); + return !isNaN(relevance) && relevance >= threshold; + }); + } + + // Sort by relevance (highest first) so limit keeps the most relevant items + if (hasLimit) { + filtered = filtered.sort((a, b) => { + const relA = parseFloat(a?.relevance) || 0; + const relB = parseFloat(b?.relevance) || 0; + return relB - relA; // Descending order + }); + filtered = filtered.slice(0, limit); + } + + return filtered; +} + +/** + * Maps tier configuration keys to API response keys. + */ +const TIER_KEY_MAP = { + ContentTier1: "iab_tier_1", + ContentTier2: "iab_tier_2", + ContentTier3: "iab_tier_3", + AudienceTier3: "iab_audience_tier_3", + AudienceTier4: "iab_audience_tier_4", + AudienceTier5: "iab_audience_tier_5", +}; + +/** + * v1 API specific + * Applies per-tier filtering to IAB taxonomies (client-side filtering for legacy endpoints). + * Filters taxonomies by relevance score and limits the count per tier. + * + * @param {Object} marketingCategories Marketing categories from legacy API response. + * @param {Object} [tierFilters] Per-tier filter configuration with human-readable tier names (e.g., {ContentTier1: {limit: 3, threshold: 0.75}}). + * @returns {Object} Filtered marketing categories with the same structure as input. + */ +export function filterIabTaxonomies(marketingCategories, tierFilters = {}) { + if (!marketingCategories || typeof marketingCategories !== "object") { + return marketingCategories; + } + + // If no filters provided, return original data + if (!tierFilters || Object.keys(tierFilters).length === 0) { + logInfo( + MODULE_NAME, + "filterIabTaxonomies():", + "No filters provided, returning original data" + ); + return marketingCategories; + } + + const filtered = {}; + + // Iterate through all tiers in the API response + Object.keys(marketingCategories).forEach((apiTierKey) => { + const tierData = marketingCategories[apiTierKey]; + + // Find the corresponding config key for this API tier + const configTierKey = Object.keys(TIER_KEY_MAP).find( + (key) => TIER_KEY_MAP[key] === apiTierKey + ); + + // Get filter for this tier (if configured) + const filter = configTierKey ? tierFilters[configTierKey] : {}; + + // Apply filter if this tier has data if (Array.isArray(tierData)) { - tierData.forEach((item) => { - const ID = item?.ID; - const label = item?.label; + filtered[apiTierKey] = filterIabTaxonomyTier(tierData, filter); + } else { + // Preserve non-array data as-is + filtered[apiTierKey] = tierData; + } + }); + + logInfo( + MODULE_NAME, + "filterIabTaxonomies():", + "Filtering results:", + "Original:", + marketingCategories, + "Filtered:", + filtered + ); + + return filtered; +} + +/** + * v1 API specific + * Transforms legacy API response format to unified internal format. + * Converts marketing_categories structure to segtax-based structure for consistent processing. + * + * Legacy format: { marketing_categories: { iab_tier_1: [...], iab_audience_tier_3: [...] } } + * Unified format: { "6": { "1": [...], "2": [...] }, "4": { "3": [...], "4": [...] } } + * + * @param {Object} v1Response The legacy API response with marketing_categories structure. + * @param {number} contentSegtax The segtax ID for content taxonomies (determined by iabContentTaxonomyVersion). + * @returns {Object} Unified format response keyed by segtax and tier numbers. + */ +export function transformV1ResponseToV2(v1Response, contentSegtax) { + const marketingCategories = v1Response?.marketing_categories || {}; + const contentSegtaxStr = String(contentSegtax); + const result = {}; + + // Content tiers: keyed by segtax from config + result[contentSegtaxStr] = {}; + if (marketingCategories.iab_tier_1) { + result[contentSegtaxStr]["1"] = transformSegmentsV1ToV2( + marketingCategories.iab_tier_1 + ); + } + if (marketingCategories.iab_tier_2) { + result[contentSegtaxStr]["2"] = transformSegmentsV1ToV2( + marketingCategories.iab_tier_2 + ); + } + if (marketingCategories.iab_tier_3) { + result[contentSegtaxStr]["3"] = transformSegmentsV1ToV2( + marketingCategories.iab_tier_3 + ); + } - if (ID && label) { - data.segment.push({ id: ID, name: label }); + // Audience tiers: segtax 4 + result["4"] = {}; + if (marketingCategories.iab_audience_tier_3) { + result["4"]["3"] = transformSegmentsV1ToV2( + marketingCategories.iab_audience_tier_3 + ); + } + if (marketingCategories.iab_audience_tier_4) { + result["4"]["4"] = transformSegmentsV1ToV2( + marketingCategories.iab_audience_tier_4 + ); + } + if (marketingCategories.iab_audience_tier_5) { + result["4"]["5"] = transformSegmentsV1ToV2( + marketingCategories.iab_audience_tier_5 + ); + } + + return result; +} + +/** + * v1 API specific + * Transforms segment objects from legacy format to unified format. + * Maps field names from legacy API response to unified internal representation. + * + * Legacy format: { ID: "123", label: "Category Name", relevance: "0.95" } + * Unified format: { id: "123", name: "Category Name", relevance: "0.95" } + * + * @param {Array} segments Array of legacy segment objects with ID, label, relevance. + * @returns {Array} Array of unified format segment objects with id, name, relevance. + */ +export function transformSegmentsV1ToV2(segments) { + if (!Array.isArray(segments)) return []; + return segments.map((seg) => ({ + id: seg.ID, + name: seg.label, + relevance: seg.relevance, + })); +} + +/** + * Builds flattened query parameters from IAB taxonomy filters. + * Converts human-readable tier names directly to query parameter format for GET requests. + * + * @param {Object} iabTaxonomyFilters Publisher's tier filter configuration using human-readable tier names. + * @param {number} contentSegtax The segtax ID for content taxonomies (determined by iabContentTaxonomyVersion). + * @param {boolean} [enableOrtb25Fields=true] If true, also applies filters to IAB Content Taxonomy 1.0 (segtax 1) for OpenRTB 2.5 category fields. + * @returns {Array} Array of query parameter strings (e.g., ["filter_6_1_limit=3", "filter_6_1_threshold=0.5"]). + * + * @example + * Input: { ContentTier1: { limit: 3, threshold: 0.5 }, AudienceTier3: { limit: 2 } }, contentSegtax=6 + * Output: ["filter_6_1_limit=3", "filter_6_1_threshold=0.5", "filter_4_3_limit=2"] + */ +export function buildFilterQueryParams( + iabTaxonomyFilters, + contentSegtax, + enableOrtb25Fields = true +) { + const params = []; + + if (!iabTaxonomyFilters || typeof iabTaxonomyFilters !== "object") { + return params; + } + + const TIER_TO_SEGTAX = { + ContentTier1: { segtax: contentSegtax, tier: "1" }, + ContentTier2: { segtax: contentSegtax, tier: "2" }, + ContentTier3: { segtax: contentSegtax, tier: "3" }, + AudienceTier3: { segtax: 4, tier: "3" }, + AudienceTier4: { segtax: 4, tier: "4" }, + AudienceTier5: { segtax: 4, tier: "5" }, + }; + + // Build query params from tier mappings + Object.entries(iabTaxonomyFilters).forEach(([tierName, filter]) => { + const mapping = TIER_TO_SEGTAX[tierName]; + if (mapping && filter && typeof filter === "object") { + const segtax = mapping.segtax; + const tier = mapping.tier; + + // Add each filter property (limit, threshold) as a query parameter + Object.keys(filter).forEach((prop) => { + const value = filter[prop]; + if (value !== undefined && value !== null) { + params.push(`filter_${segtax}_${tier}_${prop}=${value}`); } }); } }); - return data; + // Apply same filters to IAB 1.0 (segtax 1) for OpenRTB 2.5 fields. + // Skip when contentSegtax is already 1 -- the first loop already emitted filter_1_* params. + // Note: IAB 1.0 only has tiers 1 and 2 (tier 3 will be ignored if configured) + if (enableOrtb25Fields && contentSegtax !== 1) { + if (iabTaxonomyFilters.ContentTier1) { + Object.keys(iabTaxonomyFilters.ContentTier1).forEach((prop) => { + const value = iabTaxonomyFilters.ContentTier1[prop]; + if (value !== undefined && value !== null) { + params.push(`filter_1_1_${prop}=${value}`); + } + }); + } + + if (iabTaxonomyFilters.ContentTier2) { + Object.keys(iabTaxonomyFilters.ContentTier2).forEach((prop) => { + const value = iabTaxonomyFilters.ContentTier2[prop]; + if (value !== undefined && value !== null) { + params.push(`filter_1_2_${prop}=${value}`); + } + }); + } + } + + return params; } /** - * Processes the Neuwo API response to build and inject IAB content and audience categories - * into the bid request object. + * Processes the Neuwo API response and injects IAB Content and Audience Segments into the bid request. + * Extracts Segments from the response and injects them into ORTB2 structure. + * + * Response format: { "6": { "1": [{id, name}], "2": [...] }, "4": { "3": [...], "4": [...] } } + * - Content taxonomies are injected into ortb2.site.content.data + * - Audience taxonomies are injected into ortb2.user.data + * - If enableOrtb25Fields is true, IAB 1.0 segments are injected into OpenRTB 2.5 category fields * - * @param {Object} responseParsed The parsed JSON response from the Neuwo API. - * @param {Object} reqBidsConfigObj The bid request configuration object to be modified. - * @param {string} iabContentTaxonomyVersion The version of the IAB content taxonomy to use for segtax mapping. + * Only injects data if segments exist to avoid adding empty data structures. + * + * @param {Object} responseParsed The parsed API response. + * @param {Object} reqBidsConfigObj The bid request configuration object to be enriched. + * @param {string} iabContentTaxonomyVersion The IAB Content Taxonomy version for segtax mapping. + * @param {boolean} [enableOrtb25Fields=true] If true, populates OpenRTB 2.5 category fields with IAB Content Taxonomy 1.0 segments. */ -function injectIabCategories(responseParsed, reqBidsConfigObj, iabContentTaxonomyVersion) { - const marketingCategories = responseParsed.marketing_categories; - - if (!marketingCategories) { - logError(MODULE_NAME, "injectIabCategories:", "No Marketing Categories in Neuwo API response."); - return +export function injectIabCategories( + responseParsed, + reqBidsConfigObj, + iabContentTaxonomyVersion, + enableOrtb25Fields = true +) { + if (!responseParsed || typeof responseParsed !== "object") { + logError(MODULE_NAME, "injectIabCategories():", "Invalid response format"); + return; } - // Process content categories - const contentTiers = ["iab_tier_1", "iab_tier_2", "iab_tier_3"]; - const contentData = buildIabData( - marketingCategories, - contentTiers, - IAB_CONTENT_TAXONOMY_MAP[iabContentTaxonomyVersion] || IAB_CONTENT_TAXONOMY_MAP["3.0"] - ); + const contentSegtax = + IAB_CONTENT_TAXONOMY_MAP[iabContentTaxonomyVersion] || + IAB_CONTENT_TAXONOMY_MAP[DEFAULT_IAB_CONTENT_TAXONOMY_VERSION]; + const contentSegtaxStr = String(contentSegtax); + + // Extract IAB Content Taxonomy data for the configured version + const contentTiers = responseParsed[contentSegtaxStr] || {}; + const contentData = buildIabData(contentTiers, contentSegtax); + + // Extract IAB Audience Taxonomy data + const audienceTiers = responseParsed["4"] || {}; + const audienceData = buildIabData(audienceTiers, 4); - // Process audience categories - const audienceTiers = ["iab_audience_tier_3", "iab_audience_tier_4", "iab_audience_tier_5"]; - const audienceData = buildIabData(marketingCategories, audienceTiers, 4); + logInfo( + MODULE_NAME, + "injectIabCategories():", + "contentData structure:", + contentData + ); + logInfo( + MODULE_NAME, + "injectIabCategories():", + "audienceData structure:", + audienceData + ); - logInfo(MODULE_NAME, "injectIabCategories:", "contentData structure:", contentData); - logInfo(MODULE_NAME, "injectIabCategories:", "audienceData structure:", audienceData); + // Inject content and audience data independently to avoid sending empty structures + if (contentData.segment.length > 0) { + injectOrtbData(reqBidsConfigObj, "site.content.data", [contentData]); + logInfo( + MODULE_NAME, + "injectIabCategories():", + "Injected content data into site.content.data" + ); + } else { + logInfo( + MODULE_NAME, + "injectIabCategories():", + "No content segments to inject, skipping site.content.data" + ); + } - injectOrtbData(reqBidsConfigObj, "site.content.data", [contentData]); - injectOrtbData(reqBidsConfigObj, "user.data", [audienceData]); + if (audienceData.segment.length > 0) { + injectOrtbData(reqBidsConfigObj, "user.data", [audienceData]); + logInfo( + MODULE_NAME, + "injectIabCategories():", + "Injected audience data into user.data" + ); + } else { + logInfo( + MODULE_NAME, + "injectIabCategories():", + "No audience segments to inject, skipping user.data" + ); + } - logInfo(MODULE_NAME, "injectIabCategories:", "post-injection bidsConfig", reqBidsConfigObj); + // Inject OpenRTB 2.5 category fields if feature enabled + if (enableOrtb25Fields) { + const iab10Tiers = responseParsed["1"] || {}; // Segtax 1 = IAB Content 1.0 + const categoryIds = extractCategoryIds(iab10Tiers); // ["IAB12", "IAB12-3", ...] + + if (categoryIds.length > 0) { + // Inject same array into all four OpenRTB 2.5 category fields + injectOrtbData(reqBidsConfigObj, "site.cat", categoryIds); + injectOrtbData(reqBidsConfigObj, "site.sectioncat", categoryIds); + injectOrtbData(reqBidsConfigObj, "site.pagecat", categoryIds); + injectOrtbData(reqBidsConfigObj, "site.content.cat", categoryIds); + + logInfo( + MODULE_NAME, + "injectIabCategories():", + "Injected OpenRTB 2.5 category fields:", + categoryIds + ); + } else { + logInfo( + MODULE_NAME, + "injectIabCategories():", + "No IAB 1.0 segments available for OpenRTB 2.5 fields" + ); + } + } } export const neuwoRtdModule = { diff --git a/modules/neuwoRtdProvider.md b/modules/neuwoRtdProvider.md index 804130be1e6..e6c2798a1ad 100644 --- a/modules/neuwoRtdProvider.md +++ b/modules/neuwoRtdProvider.md @@ -10,55 +10,47 @@ The Neuwo RTD provider fetches real-time contextual data from the Neuwo API. Whe This data is then added to the bid request by populating the OpenRTB 2.x objects `ortb2.site.content.data` (for IAB Content Taxonomy) and `ortb2.user.data` (for IAB Audience Taxonomy). This enrichment allows bidders to leverage Neuwo's contextual analysis for more precise targeting and decision-making. +Additionally, when enabled, the module populates OpenRTB 2.5 category fields (`ortb2.site.cat`, `ortb2.site.sectioncat`, `ortb2.site.pagecat`, `ortb2.site.content.cat`) with IAB Content Taxonomy 1.0 segments. + Here is an example scheme of the data injected into the `ortb2` object by our module: ```javascript ortb2: { site: { + // OpenRTB 2.5 category fields (IAB Content Taxonomy 1.0) + cat: ["IAB12", "IAB12-3", "IAB12-5"], + sectioncat: ["IAB12", "IAB12-3", "IAB12-5"], + pagecat: ["IAB12", "IAB12-3", "IAB12-5"], content: { + // OpenRTB 2.5 category field (IAB Content Taxonomy 1.0) + cat: ["IAB12", "IAB12-3", "IAB12-5"], // IAB Content Taxonomy data is injected here data: [{ name: "www.neuwo.ai", - segment: [{ - id: "274", - name: "Home & Garden", - }, - { - id: "42", - name: "Books and Literature", - }, - { - id: "210", - name: "Food & Drink", - }, + segment: [ + { id: "274" }, + { id: "42" }, + { id: "210" }, ], ext: { - segtax: 7, + segtax: 6, }, - }, ], + }], }, }, user: { // IAB Audience Taxonomy data is injected here data: [{ name: "www.neuwo.ai", - segment: [{ - id: "49", - name: "Demographic | Gender | Female |", - }, - { - id: "161", - name: "Demographic | Marital Status | Married |", - }, - { - id: "6", - name: "Demographic | Age Range | 30-34 |", - }, + segment: [ + { id: "49" }, + { id: "161" }, + { id: "6" }, ], ext: { segtax: 4, }, - }, ], + }], }, } ``` @@ -74,16 +66,17 @@ This module is configured as part of the `realTimeData.dataProviders` object. ```javascript pbjs.setConfig({ realTimeData: { - auctionDelay: 500, // Value can be adjusted based on the needs + auctionDelay: 500, // Value can be adjusted based on the needs. Recommended to start with value `500` dataProviders: [ { name: "NeuwoRTDModule", - waitForIt: true, + waitForIt: true, // Recommended to be set to `true` params: { neuwoApiUrl: "", neuwoApiToken: "", - iabContentTaxonomyVersion: "3.0", + iabContentTaxonomyVersion: "2.2", enableCache: true, // Default: true. Caches API responses to avoid redundant requests + enableOrtb25Fields: true, // Default: true. }, }, ], @@ -93,23 +86,61 @@ pbjs.setConfig({ **Parameters** -| Name | Type | Required | Default | Description | -| :---------------------------------- | :------- | :------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | String | Yes | | The name of the module, which is `NeuwoRTDModule`. | -| `params` | Object | Yes | | Container for module-specific parameters. | -| `params.neuwoApiUrl` | String | Yes | | The endpoint URL for the Neuwo Edge API. | -| `params.neuwoApiToken` | String | Yes | | Your unique API token provided by Neuwo. | -| `params.iabContentTaxonomyVersion` | String | No | `'3.0'` | Specifies the version of the IAB Content Taxonomy to be used. Supported values: `'2.2'`, `'3.0'`. | -| `params.enableCache` | Boolean | No | `true` | If `true`, caches API responses to avoid redundant requests for the same page during the session. Set to `false` to disable caching and make a fresh API call on every bid request. | -| `params.stripAllQueryParams` | Boolean | No | `false` | If `true`, strips all query parameters from the URL before analysis. Takes precedence over other stripping options. | -| `params.stripQueryParamsForDomains` | String[] | No | `[]` | List of domains for which to strip **all** query parameters. When a domain matches, all query params are removed for that domain and all its subdomains (e.g., `'example.com'` strips params for both `'example.com'` and `'sub.example.com'`). This option takes precedence over `stripQueryParams` for matching domains. | -| `params.stripQueryParams` | String[] | No | `[]` | List of specific query parameter names to strip from the URL (e.g., `['utm_source', 'fbclid']`). Other parameters are preserved. Only applies when the domain does not match `stripQueryParamsForDomains`. | -| `params.stripFragments` | Boolean | No | `false` | If `true`, strips URL fragments (hash, e.g., `#section`) from the URL before analysis. | +| Name | Type | Required | Default | Description | +| :---------------------------------- | :------- | :------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | String | Yes | | The name of the module, which is `NeuwoRTDModule`. | +| `params` | Object | Yes | | Container for module-specific parameters. | +| `params.neuwoApiUrl` | String | Yes | | The endpoint URL for the Neuwo Edge API. | +| `params.neuwoApiToken` | String | Yes | | Your unique API token provided by Neuwo. | +| `params.iabContentTaxonomyVersion` | String | No | `'2.2'` | Specifies the version of the IAB Content Taxonomy to be used. Supported values: `'1.0'`, `'2.2'`, `'3.0'`. | +| `params.enableCache` | Boolean | No | `true` | If `true`, caches API responses to avoid redundant requests for the same page during the session. Set to `false` to disable caching and make a fresh API call on every bid request. | +| `params.enableOrtb25Fields` | Boolean | No | `true` | If `true`, populates OpenRTB 2.5 category fields (`ortb2.site.cat`, `ortb2.site.sectioncat`, `ortb2.site.pagecat`, `ortb2.site.content.cat`) with IAB Content Taxonomy 1.0 segments. See [OpenRTB 2.5 Category Fields](#openrtb-25-category-fields) section below for details. | +| `params.stripAllQueryParams` | Boolean | No | `false` | If `true`, strips all query parameters from the URL before analysis. Takes precedence over other stripping options. | +| `params.stripQueryParamsForDomains` | String[] | No | `[]` | List of domains for which to strip **all** query parameters. When a domain matches, all query params are removed for that domain and all its subdomains (e.g., `'example.com'` strips params for both `'example.com'` and `'sub.example.com'`). This option takes precedence over `stripQueryParams` for matching domains. | +| `params.stripQueryParams` | String[] | No | `[]` | List of specific query parameter names to strip from the URL (e.g., `['utm_source', 'fbclid']`). Other parameters are preserved. Only applies when the domain does not match `stripQueryParamsForDomains`. | +| `params.stripFragments` | Boolean | No | `false` | If `true`, strips URL fragments (hash, e.g., `#section`) from the URL before analysis. | +| `params.iabTaxonomyFilters` | Object | No | | Per-tier filtering configuration for IAB taxonomies. Allows filtering by relevance threshold and limiting the count of categories per tier. Filters configured for `ContentTier1` and `ContentTier2` are automatically applied to IAB Content Taxonomy 1.0 when `enableOrtb25Fields` is `true`. See [IAB Taxonomy Filtering](#iab-taxonomy-filtering) section for details. | ### API Response Caching By default, the module caches API responses during the page session to optimise performance and reduce redundant API calls. This behaviour can be disabled by setting `enableCache: false` if needed for dynamic content scenarios. +### OpenRTB 2.5 Category Fields + +The module supports populating OpenRTB 2.5 category fields with IAB Content Taxonomy 1.0 segments. This feature is enabled by default and provides additional contextual signals to bidders through standard OpenRTB fields. + +**Category Fields Populated:** + +- `ortb2.site.cat` - Array of IAB Content Taxonomy 1.0 category IDs +- `ortb2.site.sectioncat` - Array of IAB Content Taxonomy 1.0 category IDs +- `ortb2.site.pagecat` - Array of IAB Content Taxonomy 1.0 category IDs +- `ortb2.site.content.cat` - Array of IAB Content Taxonomy 1.0 category IDs + +**Result Example:** + +With `enableOrtb25Fields: true`, the module injects: + +```javascript +ortb2: { + site: { + // OpenRTB 2.5 category fields + cat: ["IAB12", "IAB12-3", "IAB12-5"], + sectioncat: ["IAB12", "IAB12-3", "IAB12-5"], + pagecat: ["IAB12", "IAB12-3", "IAB12-5"], + content: { + // OpenRTB 2.5 category field + cat: ["IAB12", "IAB12-3", "IAB12-5"], + // Standard content data + data: [{ + name: "www.neuwo.ai", + segment: [{ id: "274" }, { id: "42" }], + ext: { segtax: 6 } + }] + } + } +} +``` + ### URL Cleaning Options The module provides optional URL cleaning capabilities to strip query parameters and/or fragments from the analysed URL before sending it to the Neuwo API. This can be useful for privacy, caching, or analytics purposes. @@ -119,15 +150,15 @@ The module provides optional URL cleaning capabilities to strip query parameters ```javascript pbjs.setConfig({ realTimeData: { - auctionDelay: 500, // Value can be adjusted based on the needs + auctionDelay: 500, // Value can be adjusted based on the needs. Recommended to start with value `500` dataProviders: [ { name: "NeuwoRTDModule", - waitForIt: true, + waitForIt: true, // Recommended to be set to `true` params: { neuwoApiUrl: "", neuwoApiToken: "", - iabContentTaxonomyVersion: "3.0", + iabContentTaxonomyVersion: "2.2", // Option 1: Strip all query parameters from the URL stripAllQueryParams: true, @@ -147,6 +178,133 @@ pbjs.setConfig({ }); ``` +### IAB Taxonomy Filtering + +The module provides optional per-tier filtering for IAB taxonomies to control the quantity and quality of categories injected into bid requests. This allows you to limit categories based on their relevance score and restrict the maximum number of categories per tier. Filtering is performed server-side, which means only the filtered categories are returned in the response. This reduces bandwidth and improves performance. + +**Filter Configuration:** + +Each tier can have two optional parameters: + +- `threshold` (Number): Minimum relevance score (0.0 to 1.0). Categories below this threshold are excluded. +- `limit` (Number): Maximum number of categories to include for this tier (after filtering and sorting by relevance). + +**Available Tiers:** + +| Tier Name | Description | IAB Taxonomy | +| :-------------- | :------------------ | :----------------------------------- | +| `ContentTier1` | IAB Content Tier 1 | Based on configured taxonomy version | +| `ContentTier2` | IAB Content Tier 2 | Based on configured taxonomy version | +| `ContentTier3` | IAB Content Tier 3 | Based on configured taxonomy version | +| `AudienceTier3` | IAB Audience Tier 3 | IAB Audience Taxonomy 1.1 (segtax 4) | +| `AudienceTier4` | IAB Audience Tier 4 | IAB Audience Taxonomy 1.1 (segtax 4) | +| `AudienceTier5` | IAB Audience Tier 5 | IAB Audience Taxonomy 1.1 (segtax 4) | + +**Example with IAB taxonomy filtering:** + +```javascript +pbjs.setConfig({ + realTimeData: { + auctionDelay: 500, // Value can be adjusted based on the needs. Recommended to start with value `500` + dataProviders: [ + { + name: "NeuwoRTDModule", + waitForIt: true, // Recommended to be set to `true` + params: { + neuwoApiUrl: "", + neuwoApiToken: "", + iabContentTaxonomyVersion: "2.2", + + // Filter IAB taxonomies by tier + iabTaxonomyFilters: { + // Content Tier 1: Keep only the top category with at least 10% relevance + ContentTier1: { limit: 1, threshold: 0.1 }, + + // Content Tier 2: Keep top 2 categories with at least 10% relevance + ContentTier2: { limit: 2, threshold: 0.1 }, + + // Content Tier 3: Keep top 3 categories with at least 15% relevance + ContentTier3: { limit: 3, threshold: 0.15 }, + + // Audience Tier 3: Keep top 3 categories with at least 20% relevance + AudienceTier3: { limit: 3, threshold: 0.2 }, + + // Audience Tier 4: Keep top 5 categories with at least 20% relevance + AudienceTier4: { limit: 5, threshold: 0.2 }, + + // Audience Tier 5: Keep top 7 categories with at least 30% relevance + AudienceTier5: { limit: 7, threshold: 0.3 }, + }, + }, + }, + ], + }, +}); +``` + +**OpenRTB 2.5 Category Fields Filtering** + +When `iabTaxonomyFilters` are configured, the same filters applied to `ContentTier1` and `ContentTier2` are automatically applied to IAB Content Taxonomy 1.0 data used for these fields. Note that IAB Content Taxonomy 1.0 only has tiers 1 and 2, so `ContentTier3` filters are ignored for these fields. + +## Accessing Neuwo Data Outside Prebid.js + +The Neuwo RTD module enriches bid requests with contextual data that can be accessed in application code for analytics, targeting, integration with Google Ad Manager as [Publisher Provided Signals (PPS)](https://support.google.com/admanager/answer/15287325) or other purposes. The enriched data is available through Prebid.js events. + +### Example of Using the `bidRequested` Event + +Listen to the `bidRequested` event to access the enriched ORTB2 data. This event fires early in the auction lifecycle and provides direct access to the Neuwo data: + +```javascript +pbjs.que.push(function () { + pbjs.onEvent("bidRequested", function (bidRequest) { + // The ortb2 data is available directly on the bidRequest + const ortb2 = bidRequest.ortb2; + + // Extract Neuwo-specific data (from www.neuwo.ai provider) + const neuwoSiteData = ortb2?.site?.content?.data?.find( + (d) => d.name === "www.neuwo.ai" + ); + const neuwoUserData = ortb2?.user?.data?.find( + (d) => d.name === "www.neuwo.ai" + ); + + // Extract OpenRTB 2.5 category fields (if enableOrtb25Fields is true) + const categoryFields = { + siteCat: ortb2?.site?.cat, + siteSectioncat: ortb2?.site?.sectioncat, + sitePagecat: ortb2?.site?.pagecat, + contentCat: ortb2?.site?.content?.cat, + }; + + // Use the data in the application + console.log("Neuwo Site Content:", neuwoSiteData); + console.log("Neuwo User Data:", neuwoUserData); + console.log("OpenRTB 2.5 Category Fields:", categoryFields); + + // Example: Store in a global variable for later use + window.neuwoData = { + siteContent: neuwoSiteData, + user: neuwoUserData, + categoryFields: categoryFields, + }; + }); +}); +``` + +### Other Prebid.js Events + +The Neuwo data is also available in other Prebid.js events: + +| Order | Event | Fires Once Per | Data Location | +| :---- | :----------------- | :------------- | :----------------------------------- | +| 1 | `auctionInit` | Auction | `auctionData.bidderRequests[].ortb2` | +| 2 | `bidRequested` | Bidder | `bidRequest.ortb2` | +| 3 | `beforeBidderHttp` | Bidder | `bidRequests[].ortb2` | +| 4 | `bidResponse` | Bidder | `bidResponse.ortb2` | +| 5 | `auctionEnd` | Auction | `auctionData.bidderRequests[].ortb2` | + +For more information on Prebid.js events, see the [Prebid.js Event API documentation](https://docs.prebid.org/dev-docs/publisher-api-reference/getEvents.html). + ## Local Development Install the exact versions of packages specified in the lockfile: @@ -194,7 +352,7 @@ npx eslint 'modules/neuwoRtdProvider.js' --cache --cache-strategy content To run the module-specific tests: ```bash -npx gulp test-only --modules=rtdModule,neuwoRtdProvider,appnexusBidAdapter --file=test/spec/modules/euwoRtdProvider_spec.js +npx gulp test-only --modules=rtdModule,neuwoRtdProvider,appnexusBidAdapter --file=test/spec/modules/neuwoRtdProvider_spec.js ``` Skip building, if the project has already been built: @@ -202,3 +360,32 @@ Skip building, if the project has already been built: ```bash npx gulp test-only-nobuild --file=test/spec/modules/neuwoRtdProvider_spec.js ``` + +To generate test coverage report for the Neuwo RTD Module: + +```bash +npx gulp test-coverage --file=test/spec/modules/neuwoRtdProvider_spec.js +``` + +After running the coverage command, you can view the HTML report: + +```bash +# Open the coverage report in your browser +firefox build/coverage/lcov-report/index.html +# or +google-chrome build/coverage/lcov-report/index.html +``` + +Navigate to `modules/neuwoRtdProvider.js` in the report to see detailed line-by-line coverage with highlighted covered/uncovered lines. + +## Building for Production + +To generate minified code for production use: + +```bash +npx gulp build --modules=rtdModule,neuwoRtdProvider +``` + +This command creates optimised, minified code typically used on websites. + +> Version **2.2.6** diff --git a/modules/nextMillenniumBidAdapter.js b/modules/nextMillenniumBidAdapter.js index ec089e151aa..b5766b30607 100644 --- a/modules/nextMillenniumBidAdapter.js +++ b/modules/nextMillenniumBidAdapter.js @@ -13,14 +13,14 @@ import { triggerPixel, } from '../src/utils.js'; -import {getAd} from '../libraries/targetVideoUtils/bidderUtils.js'; +import { getAd } from '../libraries/targetVideoUtils/bidderUtils.js'; import { EVENTS } from '../src/constants.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; @@ -180,7 +180,7 @@ export const spec = { _each(validBidRequests, (bid, i) => { window.nmmRefreshCounts[bid.adUnitCode] = window.nmmRefreshCounts[bid.adUnitCode] || 0; const id = getPlacementId(bid); - const {cur, mediaTypes} = getCurrency(bid); + const { cur, mediaTypes } = getCurrency(bid); if (i === 0) postBody.cur = cur; const impId = String(i + 1) @@ -218,7 +218,7 @@ export const spec = { _each(resp.bid, (bid) => { const requestId = bidRequest.bidIds.get(bid.impid); - const {ad, adUrl, vastUrl, vastXml} = getAd(bid); + const { ad, adUrl, vastUrl, vastXml } = getAd(bid); const bidResponse = { requestId, @@ -259,7 +259,7 @@ export const spec = { if (!syncOptions.iframeEnabled && !syncOptions.pixelEnabled) return []; const pixels = []; - const getSetPixelFunc = type => url => { pixels.push({type, url: replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent, type)}) }; + const getSetPixelFunc = type => url => { pixels.push({ type, url: replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent, type) }) }; const getSetPixelsFunc = type => response => { deepAccess(response, `body.ext.sync.${type}`, []).forEach(getSetPixelFunc(type)) }; const setPixel = (type, url) => { (getSetPixelFunc(type))(url) }; @@ -337,7 +337,7 @@ export const spec = { export function getExtNextMilImp(impId, bid) { if (typeof window?.nmmRefreshCounts[bid.adUnitCode] === 'number') ++window.nmmRefreshCounts[bid.adUnitCode]; - const {adSlots, allowedAds} = bid.params + const { adSlots, allowedAds } = bid.params const nextMilImp = { impId, nextMillennium: { @@ -355,7 +355,7 @@ export function getExtNextMilImp(impId, bid) { } export function getImp(impId, bid, id, mediaTypes) { - const {banner, video} = mediaTypes; + const { banner, video } = mediaTypes; const imp = { id: impId, ext: { @@ -382,8 +382,8 @@ export function getImpBanner(imp, banner) { if (banner.bidfloorcur) imp.bidfloorcur = banner.bidfloorcur; if (banner.bidfloor) imp.bidfloor = banner.bidfloor; - const format = (banner.data?.sizes || []).map(s => { return {w: s[0], h: s[1]} }); - const {w, h} = (format[0] || {}) + const format = (banner.data?.sizes || []).map(s => { return { w: s[0], h: s[1] } }); + const { w, h } = (format[0] || {}) imp.banner = { w, h, @@ -499,13 +499,13 @@ function getCurrency(bid = {}) { for (const mediaType of types) { const mediaTypeData = deepAccess(bid, `mediaTypes.${mediaType}`); if (mediaTypeData) { - mediaTypes[mediaType] = {data: mediaTypeData}; + mediaTypes[mediaType] = { data: mediaTypeData }; } else { continue; }; if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency, mediaType, size: '*'}); + const floorInfo = bid.getFloor({ currency, mediaType, size: '*' }); mediaTypes[mediaType].bidfloorcur = floorInfo?.currency; mediaTypes[mediaType].bidfloor = floorInfo?.floor; } else { @@ -517,7 +517,7 @@ function getCurrency(bid = {}) { if (!cur.length) cur.push(DEFAULT_CURRENCY); - return {cur, mediaTypes}; + return { cur, mediaTypes }; } export function getPlacementId(bid) { @@ -611,13 +611,13 @@ export function getSourceObj(validBidRequests, bidderRequest) { } function getSua() { - const {brands, mobile, platform} = (window?.navigator?.userAgentData || {}); + const { brands, mobile, platform } = (window?.navigator?.userAgentData || {}); if (!(brands && platform)) return undefined; return { browsers: brands, mobile: Number(!!mobile), - platform: (platform && {brand: platform}) || undefined, + platform: (platform && { brand: platform }) || undefined, }; } diff --git a/modules/nextrollBidAdapter.js b/modules/nextrollBidAdapter.js index 92fc2222fb2..8ac2b977a32 100644 --- a/modules/nextrollBidAdapter.js +++ b/modules/nextrollBidAdapter.js @@ -6,9 +6,10 @@ import { isPlainObject, isStr, parseUrl, - replaceAuctionPrice} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; + replaceAuctionPrice +} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { getOsVersion } from '../libraries/advangUtils/index.js'; @@ -104,7 +105,7 @@ export const spec = { function _getBanner(bidRequest) { const sizes = _getSizes(bidRequest); if (sizes === undefined) return undefined; - return {format: sizes}; + return { format: sizes }; } function _getNative(mediaTypeNative) { @@ -128,12 +129,12 @@ function _getNative(mediaTypeNative) { required: Overrides the asset required field configured, only overrides when is true. */ const NATIVE_ASSET_MAP = [ - {id: 1, kind: 'title', key: 'title', required: true}, - {id: 2, kind: 'img', key: 'image', type: 3, required: true}, - {id: 3, kind: 'img', key: 'icon', type: 1}, - {id: 4, kind: 'img', key: 'logo', type: 2}, - {id: 5, kind: 'data', key: 'sponsoredBy', type: 1}, - {id: 6, kind: 'data', key: 'body', type: 2} + { id: 1, kind: 'title', key: 'title', required: true }, + { id: 2, kind: 'img', key: 'image', type: 3, required: true }, + { id: 3, kind: 'img', key: 'icon', type: 1 }, + { id: 4, kind: 'img', key: 'logo', type: 2 }, + { id: 5, kind: 'data', key: 'sponsoredBy', type: 1 }, + { id: 6, kind: 'data', key: 'body', type: 2 } ]; const ASSET_KIND_MAP = { @@ -154,7 +155,7 @@ function _getAsset(mediaTypeNative, assetMap) { } function _getTitleAsset(title, _assetMap) { - return {len: title.len || 0}; + return { len: title.len || 0 }; } function _getMinAspectRatio(aspectRatio, property) { diff --git a/modules/nexverseBidAdapter.js b/modules/nexverseBidAdapter.js index 25d52000a82..a52bc9ffa4c 100644 --- a/modules/nexverseBidAdapter.js +++ b/modules/nexverseBidAdapter.js @@ -1,13 +1,13 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; import { isArray, generateUUID, getWinDimensions, isNumber } from '../src/utils.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; -import {getConnectionType} from '../libraries/connectionInfo/connectionUtils.js' +import { getConnectionType } from '../libraries/connectionInfo/connectionUtils.js' import { getDeviceType } from '../libraries/userAgentUtils/index.js'; import { getDeviceModel, buildEndpointUrl, isBidRequestValid, parseNativeResponse, printLog, getUid, getBidFloor, getOsInfo } from '../libraries/nexverseUtils/index.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { config } from '../src/config.js'; const BIDDER_CODE = 'nexverse'; @@ -17,7 +17,7 @@ const DEFAULT_CURRENCY = 'USD'; const BID_TTL = 300; const DEFAULT_LANG = 'en'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: BIDDER_CODE}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, diff --git a/modules/nexx360BidAdapter.ts b/modules/nexx360BidAdapter.ts index a5aa9e92dd7..513efd89100 100644 --- a/modules/nexx360BidAdapter.ts +++ b/modules/nexx360BidAdapter.ts @@ -1,8 +1,8 @@ import { deepSetValue, generateUUID, logError } from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {AdapterRequest, BidderSpec, registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { getStorageManager } from '../src/storageManager.js'; +import { AdapterRequest, BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { interpretResponse, enrichImp, enrichRequest, getAmxId, getLocalStorageFunctionGenerator, getUserSyncs } from '../libraries/nexx360Utils/index.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; @@ -142,7 +142,7 @@ const buildRequests = ( bidRequests: BidRequest[], bidderRequest: ClientBidderRequest, ): AdapterRequest => { - const data:ORTBRequest = converter.toORTB({bidRequests, bidderRequest}) + const data:ORTBRequest = converter.toORTB({ bidRequests, bidderRequest }) const adapterRequest:AdapterRequest = { method: 'POST', url: REQUEST_URL, diff --git a/modules/nobidAnalyticsAdapter.js b/modules/nobidAnalyticsAdapter.js index 37064938b2a..484e4dc2b2f 100644 --- a/modules/nobidAnalyticsAdapter.js +++ b/modules/nobidAnalyticsAdapter.js @@ -1,10 +1,10 @@ -import {deepClone, logError, getParameterByName, logMessage} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { deepClone, logError, getParameterByName, logMessage } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const VERSION = '2.0.2'; const MODULE_NAME = 'nobidAnalyticsAdapter'; @@ -15,7 +15,7 @@ window.nobidAnalyticsVersion = VERSION; const analyticsType = 'endpoint'; const url = 'localhost:8383/event'; const GVLID = 816; -const storage = getStorageManager({gvlid: GVLID, moduleName: MODULE_NAME, moduleType: MODULE_TYPE_ANALYTICS}); +const storage = getStorageManager({ gvlid: GVLID, moduleName: MODULE_NAME, moduleType: MODULE_TYPE_ANALYTICS }); const { AUCTION_INIT, BID_REQUESTED, @@ -113,7 +113,7 @@ function auctionInit (event) { nobidAnalytics.topLocation = event.bidderRequests[0].refererInfo.topmostLocation; } } -let nobidAnalytics = Object.assign(adapter({url, analyticsType}), { +let nobidAnalytics = Object.assign(adapter({ url, analyticsType }), { track({ eventType, args }) { switch (eventType) { case AUCTION_INIT: diff --git a/modules/nobidBidAdapter.js b/modules/nobidBidAdapter.js index c63bad76aba..7474fb6def6 100644 --- a/modules/nobidBidAdapter.js +++ b/modules/nobidBidAdapter.js @@ -16,7 +16,7 @@ import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const GVLID = 816; const BIDDER_CODE = 'nobid'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); window.nobidVersion = '1.3.4'; window.nobid = window.nobid || {}; window.nobid.bidResponses = window.nobid.bidResponses || {}; @@ -94,7 +94,7 @@ function nobidBuildRequests(bids, bidderRequest) { } var coppa = function() { if (config.getConfig('coppa') === true) { - return {'coppa': true}; + return { 'coppa': true }; } if (bids && bids.length > 0) { return bids[0].coppa @@ -139,11 +139,11 @@ function nobidBuildRequests(bids, bidderRequest) { const ids = []; if (eid.uids) { eid.uids.forEach(value => { - ids.push({'id': value.id + ''}); + ids.push({ 'id': value.id + '' }); }); } if (eid.source && ids.length > 0) { - src.push({source: eid.source, uids: ids}); + src.push({ source: eid.source, uids: ids }); } }); return src; @@ -375,7 +375,7 @@ export const spec = { code: BIDDER_CODE, gvlid: GVLID, aliases: [ - { code: 'duration'} + { code: 'duration' } ], supportedMediaTypes: [BANNER, VIDEO], /** diff --git a/modules/nodalsAiRtdProvider.js b/modules/nodalsAiRtdProvider.js index 104e91ab851..17186f0a151 100644 --- a/modules/nodalsAiRtdProvider.js +++ b/modules/nodalsAiRtdProvider.js @@ -116,7 +116,7 @@ class NodalsAiRtdProvider { } const engine = this.#initialiseEngine(config); if (!engine) { - this.#addToCommandQueue('getBidRequestData', {config, reqBidsConfigObj, callback, userConsent, storedData }); + this.#addToCommandQueue('getBidRequestData', { config, reqBidsConfigObj, callback, userConsent, storedData }); } else { try { engine.getBidRequestData( @@ -143,7 +143,7 @@ class NodalsAiRtdProvider { } const engine = this.#initialiseEngine(config); if (!engine) { - this.#addToCommandQueue('onBidResponseEvent', {config, bidResponse, userConsent, storedData }) + this.#addToCommandQueue('onBidResponseEvent', { config, bidResponse, userConsent, storedData }) return; } try { @@ -164,7 +164,7 @@ class NodalsAiRtdProvider { } const engine = this.#initialiseEngine(config); if (!engine) { - this.#addToCommandQueue('onAuctionEndEvent', {config, auctionDetails, userConsent, storedData }); + this.#addToCommandQueue('onAuctionEndEvent', { config, auctionDetails, userConsent, storedData }); return; } try { diff --git a/modules/novatiqIdSystem.js b/modules/novatiqIdSystem.js index 50478183753..edbdf6cc293 100644 --- a/modules/novatiqIdSystem.js +++ b/modules/novatiqIdSystem.js @@ -8,8 +8,8 @@ import { logInfo, getWindowLocation } from '../src/utils.js'; import { ajax } from '../src/ajax.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -92,8 +92,10 @@ export const novatiqIdSubmodule = { } else { this.sendSimpleSyncRequest(novatiqId, url); - return { 'id': novatiqId, - 'sharedStatus': sharedStatus } + return { + 'id': novatiqId, + 'sharedStatus': sharedStatus + } } }, @@ -124,7 +126,7 @@ export const novatiqIdSubmodule = { undefined, { method: 'GET', withCredentials: false }); } - return {callback: resp}; + return { callback: resp }; }, sendSimpleSyncRequest(novatiqId, url) { @@ -225,7 +227,7 @@ export const novatiqIdSubmodule = { let sharedId = null; if (this.useSharedId(configParams)) { const cookieOrStorageID = this.getCookieOrStorageID(configParams); - const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); + const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); // first check local storage if (storage.hasLocalStorage()) { diff --git a/modules/oguryBidAdapter.js b/modules/oguryBidAdapter.js index 00c8bfb77ef..48cfa78e186 100644 --- a/modules/oguryBidAdapter.js +++ b/modules/oguryBidAdapter.js @@ -109,18 +109,18 @@ function getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gpp } function buildRequests(bidRequests, bidderRequest) { - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); return { method: 'POST', url: BID_HOST, data, - options: {contentType: 'application/json'}, + options: { contentType: 'application/json' }, }; } function interpretResponse(response, request) { - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; } function getFloor(bid) { @@ -153,7 +153,7 @@ function onBidWon(bid) { } function onTimeout(timeoutData) { - ajax(`${TIMEOUT_MONITORING_HOST}/bid_timeout`, null, JSON.stringify({...timeoutData[0], location: window.location.href}), { + ajax(`${TIMEOUT_MONITORING_HOST}/bid_timeout`, null, JSON.stringify({ ...timeoutData[0], location: window.location.href }), { method: 'POST', contentType: 'application/json' }); diff --git a/modules/omnidexBidAdapter.js b/modules/omnidexBidAdapter.js index 6fd1f34cf21..d83449edb73 100644 --- a/modules/omnidexBidAdapter.js +++ b/modules/omnidexBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { isBidRequestValid, onBidWon, @@ -13,14 +13,14 @@ const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'omnidex'; const BIDDER_VERSION = '1.0.0'; const GVLID = 1463; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.omni-dex.io`; } function createUniqueRequestData(hashUrl, bid) { - const {auctionId, transactionId} = bid; + const { auctionId, transactionId } = bid; return { auctionId, transactionId diff --git a/modules/omsBidAdapter.js b/modules/omsBidAdapter.js index fd7be06409e..99efb9198e5 100644 --- a/modules/omsBidAdapter.js +++ b/modules/omsBidAdapter.js @@ -1,21 +1,18 @@ import { - isArray, - getWindowTop, deepSetValue, logError, logWarn, - createTrackPixelHtml, getBidIdParameter, getUniqueIdentifierStr, formatQS, + deepAccess, } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; -import {percentInView} from '../libraries/percentInView/percentInView.js'; -import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js'; -import {getMinSize} from '../libraries/sizeUtils/sizeUtils.js'; -import {getBidFloor, isIframe} from '../libraries/omsUtils/index.js'; +import { ajax } from '../src/ajax.js'; +import { getUserSyncParams } from '../libraries/userSyncUtils/userSyncUtils.js'; +import { getAdMarkup, getBidFloor, getDeviceType, getProcessedSizes } from '../libraries/omsUtils/index.js'; +import { getRoundedViewability } from '../libraries/omsUtils/viewability.js'; const BIDDER_CODE = 'oms'; const URL = 'https://rt.marphezis.com/hb'; @@ -38,19 +35,14 @@ export const spec = { function buildRequests(bidReqs, bidderRequest) { try { const impressions = bidReqs.map(bid => { - let bidSizes = bid?.mediaTypes?.banner?.sizes || bid.sizes || []; - bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => isArray(size)); - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); - - const element = document.getElementById(bid.adUnitCode); - const minSize = getMinSize(processedSizes); - const viewabilityAmount = _isViewabilityMeasurable(element) ? _getViewability(element, getWindowTop(), minSize) : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); + const bidSizes = bid?.mediaTypes?.banner?.sizes || bid.sizes || []; + const processedSizes = getProcessedSizes(bidSizes); + const viewabilityAmountRounded = getRoundedViewability(bid.adUnitCode, processedSizes); const gpidData = _extractGpidData(bid); const imp = { id: bid.bidId, + displaymanagerver: '$prebid.version$', ext: { ...gpidData }, @@ -72,6 +64,10 @@ function buildRequests(bidReqs, bidderRequest) { } } + if (deepAccess(bid, 'ortb2Imp.instl') === 1) { + imp.instl = 1; + } + const bidFloor = getBidFloor(bid); if (bidFloor) { @@ -95,7 +91,7 @@ function buildRequests(bidReqs, bidderRequest) { } }, device: { - devicetype: _getDeviceType(navigator.userAgent, bidderRequest?.ortb2?.device?.sua), + devicetype: getDeviceType(navigator.userAgent, bidderRequest?.ortb2?.device?.sua), w: screen.width, h: screen.height }, @@ -143,7 +139,7 @@ function buildRequests(bidReqs, bidderRequest) { data: JSON.stringify(payload), }; } catch (e) { - logError(e, {bidReqs, bidderRequest}); + logError(e, { bidReqs, bidderRequest }); } } @@ -162,7 +158,7 @@ function interpretResponse(serverResponse) { return response; } - const {body: {id, seatbid}} = serverResponse; + const { body: { id, seatbid } } = serverResponse; try { if (id && seatbid && seatbid.length > 0 && seatbid[0].bid && seatbid[0].bid.length > 0) { @@ -186,14 +182,14 @@ function interpretResponse(serverResponse) { bidResponse.vastXml = bid.adm; } else { bidResponse.mediaType = BANNER; - bidResponse.ad = _getAdMarkup(bid); + bidResponse.ad = getAdMarkup(bid); } return bidResponse; }); } } catch (e) { - logError(e, {id, seatbid}); + logError(e, { id, seatbid }); } return response; @@ -238,18 +234,6 @@ function _trackEvent(endpoint, data) { }); } -function _getDeviceType(ua, sua) { - if (sua?.mobile || (/(ios|ipod|ipad|iphone|android)/i).test(ua)) { - return 1 - } - - if ((/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(ua)) { - return 3 - } - - return 2 -} - function _getGpp(bidderRequest) { if (bidderRequest?.gppConsent != null) { return bidderRequest.gppConsent; @@ -260,22 +244,6 @@ function _getGpp(bidderRequest) { ); } -function _getAdMarkup(bid) { - let adm = bid.adm; - if ('nurl' in bid) { - adm += createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !isIframe() && element !== null; -} - -function _getViewability(element, topWin, {w, h} = {}) { - return getWindowTop().document.visibilityState === 'visible' ? percentInView(element, {w, h}) : 0; -} - function _extractGpidData(bid) { return { gpid: bid?.ortb2Imp?.ext?.gpid, diff --git a/modules/oneKeyIdSystem.js b/modules/oneKeyIdSystem.js index 5528212531d..5e8ef101bd3 100644 --- a/modules/oneKeyIdSystem.js +++ b/modules/oneKeyIdSystem.js @@ -5,7 +5,7 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; +import { submodule } from '../src/hook.js'; import { logError, logMessage } from '../src/utils.js'; /** @@ -89,7 +89,7 @@ export const oneKeyIdSubmodule = { atype: 1, getEidExt: function(data) { if (data && data.preferences) { - return {preferences: data.preferences}; + return { preferences: data.preferences }; } }, getUidExt: function(data) { diff --git a/modules/onomagicBidAdapter.js b/modules/onomagicBidAdapter.js index c3176d7abcc..ef4d3df777e 100644 --- a/modules/onomagicBidAdapter.js +++ b/modules/onomagicBidAdapter.js @@ -1,17 +1,14 @@ import { _each, - createTrackPixelHtml, getBidIdParameter, + getBidIdParameter, getUniqueIdentifierStr, - getWindowTop, - isArray, logError, logWarn } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import { percentInView } from '../libraries/percentInView/percentInView.js'; -import {getMinSize} from '../libraries/sizeUtils/sizeUtils.js'; -import {getBidFloor, isIframe} from '../libraries/omsUtils/index.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { getAdMarkup, getBidFloor, getDeviceType, getProcessedSizes } from '../libraries/omsUtils/index.js'; +import { getRoundedViewability } from '../libraries/omsUtils/viewability.js'; const BIDDER_CODE = 'onomagic'; const URL = 'https://bidder.onomagic.com/hb'; @@ -34,17 +31,9 @@ function buildRequests(bidReqs, bidderRequest) { const onomagicImps = []; const publisherId = getBidIdParameter('publisherId', bidReqs[0].params); _each(bidReqs, function (bid) { - let bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; - bidSizes = ((isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes]); - bidSizes = bidSizes.filter(size => isArray(size)); - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})); - - const element = document.getElementById(bid.adUnitCode); - const minSize = getMinSize(processedSizes); - const viewabilityAmount = _isViewabilityMeasurable(element) - ? _getViewability(element, getWindowTop(), minSize) - : 'na'; - const viewabilityAmountRounded = isNaN(viewabilityAmount) ? viewabilityAmount : Math.round(viewabilityAmount); + const bidSizes = (bid.mediaTypes && bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) || bid.sizes; + const processedSizes = getProcessedSizes(bidSizes); + const viewabilityAmountRounded = getRoundedViewability(bid.adUnitCode, processedSizes); const imp = { id: bid.bidId, @@ -74,7 +63,7 @@ function buildRequests(bidReqs, bidderRequest) { } }, device: { - devicetype: _getDeviceType(), + devicetype: getDeviceType(), w: screen.width, h: screen.height }, @@ -85,10 +74,10 @@ function buildRequests(bidReqs, bidderRequest) { method: 'POST', url: URL, data: JSON.stringify(onomagicBidReq), - options: {contentType: 'text/plain', withCredentials: false} + options: { contentType: 'text/plain', withCredentials: false } }; } catch (e) { - logError(e, {bidReqs, bidderRequest}); + logError(e, { bidReqs, bidderRequest }); } } @@ -109,7 +98,7 @@ function interpretResponse(serverResponse) { logWarn('Onomagic server returned empty/non-json response: ' + JSON.stringify(serverResponse.body)); return []; } - const { body: {id, seatbid} } = serverResponse; + const { body: { id, seatbid } } = serverResponse; try { const onomagicBidResponses = []; if (id && @@ -127,7 +116,7 @@ function interpretResponse(serverResponse) { currency: 'USD', netRevenue: true, mediaType: BANNER, - ad: _getAdMarkup(onomagicBid), + ad: getAdMarkup(onomagicBid), ttl: 60, meta: { advertiserDomains: onomagicBid && onomagicBid.adomain ? onomagicBid.adomain : [] @@ -137,7 +126,7 @@ function interpretResponse(serverResponse) { } return onomagicBidResponses; } catch (e) { - logError(e, {id, seatbid}); + logError(e, { id, seatbid }); } } @@ -146,34 +135,4 @@ function getUserSyncs(syncOptions, responses, gdprConsent) { return []; } -function _isMobile() { - return (/(ios|ipod|ipad|iphone|android)/i).test(navigator.userAgent); -} - -function _isConnectedTV() { - return (/(smart[-]?tv|hbbtv|appletv|googletv|hdmi|netcast\.tv|viera|nettv|roku|\bdtv\b|sonydtv|inettvbrowser|\btv\b)/i).test(navigator.userAgent); -} - -function _getDeviceType() { - return _isMobile() ? 1 : _isConnectedTV() ? 3 : 2; -} - -function _getAdMarkup(bid) { - let adm = bid.adm; - if ('nurl' in bid) { - adm += createTrackPixelHtml(bid.nurl); - } - return adm; -} - -function _isViewabilityMeasurable(element) { - return !isIframe() && element !== null; -} - -function _getViewability(element, topWin, { w, h } = {}) { - return getWindowTop().document.visibilityState === 'visible' - ? percentInView(element, { w, h }) - : 0; -} - registerBidder(spec); diff --git a/modules/opaMarketplaceBidAdapter.js b/modules/opaMarketplaceBidAdapter.js index c3948a93cf1..858605ea17d 100644 --- a/modules/opaMarketplaceBidAdapter.js +++ b/modules/opaMarketplaceBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { isBidRequestValid, onBidWon, @@ -12,14 +12,14 @@ import { const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'opamarketplace'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.opamarketplace.com`; } function createUniqueRequestData(hashUrl, bid) { - const {auctionId, transactionId} = bid; + const { auctionId, transactionId } = bid; return { auctionId, transactionId diff --git a/modules/open8BidAdapter.js b/modules/open8BidAdapter.js index 49523926c0e..56dc246ace0 100644 --- a/modules/open8BidAdapter.js +++ b/modules/open8BidAdapter.js @@ -1,9 +1,9 @@ import { Renderer } from '../src/Renderer.js'; -import {ajax} from '../src/ajax.js'; -import {createTrackPixelHtml, getBidIdParameter, logError, logWarn} from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { createTrackPixelHtml, getBidIdParameter, logError, logWarn } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { VIDEO, BANNER } from '../src/mediaTypes.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const BIDDER_CODE = 'open8'; const URL = 'https://as.vt.open8.com/v1/control/prebid'; diff --git a/modules/openPairIdSystem.js b/modules/openPairIdSystem.js index 81f28734d2e..a4407dd0363 100644 --- a/modules/openPairIdSystem.js +++ b/modules/openPairIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js' -import {logInfo} from '../src/utils.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; -import {VENDORLESS_GVLID} from '../src/consentHandler.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js' +import { logInfo } from '../src/utils.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -27,7 +27,7 @@ const DEFAULT_SOURCE = 'pair-protocol.com'; const MATCH_METHOD = 3; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function publisherIdFromLocalStorage(key) { return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(key) : null; @@ -56,7 +56,7 @@ export const openPairIdSubmodule = { * @returns {{pairId:string} | undefined } */ decode(value) { - return value && Array.isArray(value) ? {'openPairId': value} : undefined; + return value && Array.isArray(value) ? { 'openPairId': value } : undefined; }, /** * Performs action to obtain ID and return a value in the callback's response argument. @@ -115,7 +115,7 @@ export const openPairIdSubmodule = { return undefined; } - return {'id': ids}; + return { 'id': ids }; }, eids: { openPairId: function(values, config = {}) { diff --git a/modules/openwebBidAdapter.js b/modules/openwebBidAdapter.js index 0dff314ce17..777c20d6f89 100644 --- a/modules/openwebBidAdapter.js +++ b/modules/openwebBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {makeBaseSpec} from '../libraries/riseUtils/index.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { makeBaseSpec } from '../libraries/riseUtils/index.js'; const BIDDER_CODE = 'openweb'; const BASE_URL = 'https://hb.openwebmp.com/'; diff --git a/modules/openxBidAdapter.js b/modules/openxBidAdapter.js index 2da04ad3e38..2e295cc8669 100644 --- a/modules/openxBidAdapter.js +++ b/modules/openxBidAdapter.js @@ -1,9 +1,9 @@ -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; -import {mergeDeep} from '../src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { mergeDeep } from '../src/utils.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const bidderConfig = 'hb_pb_ortb'; const bidderVersion = '2.0'; @@ -28,7 +28,7 @@ const converter = ortbConverter({ ttl: 300, nativeRequest: { eventtrackers: [ - {event: 1, methods: [1, 2]}, + { event: 1, methods: [1, 2] }, ] } }, @@ -89,7 +89,7 @@ const converter = ortbConverter({ }, response(buildResponse, bidResponses, ortbResponse, context) { // pass these from request to the responses for use in userSync - const {ortbRequest} = context; + const { ortbRequest } = context; if (ortbRequest.ext) { if (ortbRequest.ext.delDomain) { utils.deepSetValue(ortbResponse, 'ext.delDomain', ortbRequest.ext.delDomain); @@ -126,7 +126,7 @@ const converter = ortbConverter({ // enforce floors should always be in USD // TODO: does it make sense that request.cur can be any currency, but request.imp[].bidfloorcur must be USD? const floor = {}; - setBidFloor(floor, bidRequest, {...context, currency: 'USD'}); + setBidFloor(floor, bidRequest, { ...context, currency: 'USD' }); if (floor.bidfloorcur === 'USD') { Object.assign(imp, floor); } @@ -139,7 +139,7 @@ const converter = ortbConverter({ let videoParams = bidRequest.mediaTypes[VIDEO]; if (videoParams) { videoParams = Object.assign({}, videoParams, bidRequest.params.video); - bidRequest = {...bidRequest, mediaTypes: {[VIDEO]: videoParams}} + bidRequest = { ...bidRequest, mediaTypes: { [VIDEO]: videoParams } } } orig(imp, bidRequest, context); } @@ -165,7 +165,7 @@ function buildRequests(bidRequests, bidderRequest) { const videoRequests = bidRequests.filter(bidRequest => isVideoBidRequest(bidRequest)); const bannerAndNativeRequests = bidRequests.filter(bidRequest => isBannerBidRequest(bidRequest) || isNativeBidRequest(bidRequest)) // In case of multi-format bids remove `video` from mediaTypes as for video a separate bid request is built - .map(bid => ({...bid, mediaTypes: {...bid.mediaTypes, video: undefined}})); + .map(bid => ({ ...bid, mediaTypes: { ...bid.mediaTypes, video: undefined } })); const requests = bannerAndNativeRequests.length ? [createRequest(bannerAndNativeRequests, bidderRequest, null)] : []; videoRequests.forEach(bid => { @@ -178,7 +178,7 @@ function createRequest(bidRequests, bidderRequest, mediaType) { return { method: 'POST', url: config.getConfig('openxOrtbUrl') || REQUEST_URL, - data: converter.toORTB({bidRequests, bidderRequest, context: {mediaType}}) + data: converter.toORTB({ bidRequests, bidderRequest, context: { mediaType } }) } } @@ -197,9 +197,9 @@ function isBannerBidRequest(bidRequest) { function interpretResponse(resp, req) { if (!resp.body) { - resp.body = {nbr: 0}; + resp.body = { nbr: 0 }; } - return converter.fromORTB({request: req.data, response: resp.body}); + return converter.fromORTB({ request: req.data, response: resp.body }); } /** diff --git a/modules/operaadsBidAdapter.js b/modules/operaadsBidAdapter.js index 8645196d07d..33a86fc7330 100644 --- a/modules/operaadsBidAdapter.js +++ b/modules/operaadsBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, deepSetValue, @@ -11,12 +11,12 @@ import { logWarn, triggerPixel } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {OUTSTREAM} from '../src/video.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { OUTSTREAM } from '../src/video.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -709,7 +709,7 @@ function getUserId(bidRequest) { * @param {*} params.size * @returns {Object} floor price */ -function getBidFloor(bid, {mediaType = '*', size = '*'}) { +function getBidFloor(bid, { mediaType = '*', size = '*' }) { if (isFn(bid.getFloor)) { const floorInfo = bid.getFloor({ currency: DEFAULT_CURRENCY, diff --git a/modules/operaadsIdSystem.js b/modules/operaadsIdSystem.js index 1041237e13c..36c9f9a72d7 100644 --- a/modules/operaadsIdSystem.js +++ b/modules/operaadsIdSystem.js @@ -18,7 +18,7 @@ const ID_KEY = MODULE_NAME; const version = '1.0'; const SYNC_URL = 'https://t.adx.opera.com/identity/'; const AJAX_TIMEOUT = 300; -const AJAX_OPTIONS = {method: 'GET', withCredentials: true, contentType: 'application/json'}; +const AJAX_OPTIONS = { method: 'GET', withCredentials: true, contentType: 'application/json' }; function constructUrl(pairs) { const queries = []; diff --git a/modules/oprxBidAdapter.js b/modules/oprxBidAdapter.js index 242e95d282f..566232c4e92 100644 --- a/modules/oprxBidAdapter.js +++ b/modules/oprxBidAdapter.js @@ -51,7 +51,7 @@ const defaultConverter = ortbConverter({ }, imp(buildImp, bidRequest, context) { const imp = buildImp(bidRequest, context); - imp.ext = {bidder: bidRequest.params}; + imp.ext = { bidder: bidRequest.params }; if (bidRequest.params.bid_floor) { imp.bidfloor = bidRequest.params.bid_floor; } diff --git a/modules/opscoBidAdapter.js b/modules/opscoBidAdapter.js index 835387d9bc1..b331b9a212a 100644 --- a/modules/opscoBidAdapter.js +++ b/modules/opscoBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, deepSetValue, isArray, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' -import {pbsExtensions} from '../libraries/pbsExtensions/pbsExtensions.js'; +import { deepAccess, deepSetValue, isArray, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' +import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js'; const ENDPOINT = 'https://exchange.ops.co/openrtb2/auction'; const BIDDER_CODE = 'opsco'; @@ -12,10 +12,10 @@ const DEFAULT_NET_REVENUE = true; const converter = ortbConverter({ request(buildRequest, imps, bidderRequest, context) { - const {bidRequests} = context; + const { bidRequests } = context; const data = buildRequest(imps, bidderRequest, context); - const {publisherId, siteId} = bidRequests[0].params; + const { publisherId, siteId } = bidRequests[0].params; data.site = data.site || {}; data.site.id = siteId; @@ -120,7 +120,7 @@ export const spec = { creativeId: bid.crid, netRevenue: DEFAULT_NET_REVENUE, currency: DEFAULT_CURRENCY, - meta: {advertiserDomains: bid?.adomain || []}, + meta: { advertiserDomains: bid?.adomain || [] }, mediaType: bid.mediaType || bid.mtype })) || []; @@ -144,7 +144,7 @@ export const spec = { syncDetails.forEach(syncDetail => { const type = syncDetail.type === 'iframe' ? 'iframe' : 'image'; if ((type === 'iframe' && syncOptions.iframeEnabled) || (type === 'image' && syncOptions.pixelEnabled)) { - syncs.push({type, url: syncDetail.url}); + syncs.push({ type, url: syncDetail.url }); } }); } diff --git a/modules/optableRtdProvider.js b/modules/optableRtdProvider.js index 29638ba3a94..290c0947ee6 100644 --- a/modules/optableRtdProvider.js +++ b/modules/optableRtdProvider.js @@ -1,13 +1,13 @@ -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; -import {loadExternalScript} from '../src/adloader.js'; -import {config} from '../src/config.js'; -import {submodule} from '../src/hook.js'; -import {deepAccess, mergeDeep, prefixLog} from '../src/utils.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { config } from '../src/config.js'; +import { submodule } from '../src/hook.js'; +import { deepAccess, mergeDeep, prefixLog } from '../src/utils.js'; const MODULE_NAME = 'optable'; export const LOG_PREFIX = `[${MODULE_NAME} RTD]:`; const optableLog = prefixLog(LOG_PREFIX); -const {logMessage, logWarn, logError} = optableLog; +const { logMessage, logWarn, logError } = optableLog; /** * Extracts the parameters for Optable RTD module from the config object passed at instantiation @@ -27,15 +27,15 @@ export const parseConfig = (moduleConfig) => { // Verify that bundleUrl is a valid URL: only secure (HTTPS) URLs are allowed if (typeof bundleUrl === 'string' && bundleUrl.length && !bundleUrl.startsWith('https://')) { logError('Invalid URL format for bundleUrl in moduleConfig. Only HTTPS URLs are allowed.'); - return {bundleUrl: null, adserverTargeting, handleRtd: null}; + return { bundleUrl: null, adserverTargeting, handleRtd: null }; } if (handleRtd && typeof handleRtd !== 'function') { logError('handleRtd must be a function'); - return {bundleUrl, adserverTargeting, handleRtd: null}; + return { bundleUrl, adserverTargeting, handleRtd: null }; } - const result = {bundleUrl, adserverTargeting, handleRtd}; + const result = { bundleUrl, adserverTargeting, handleRtd }; if (instance !== null) { result.instance = instance; } @@ -118,7 +118,7 @@ export const mergeOptableData = async (handleRtdFn, reqBidsConfigObj, optableExt export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, userConsent) => { try { // Extract the bundle URL from the module configuration - const {bundleUrl, handleRtd} = parseConfig(moduleConfig); + const { bundleUrl, handleRtd } = parseConfig(moduleConfig); const handleRtdFn = handleRtd || defaultHandleRtd; const optableExtraData = config.getConfig('optableRtdConfig') || {}; @@ -162,7 +162,7 @@ export const getBidRequestData = (reqBidsConfigObj, callback, moduleConfig, user */ export const getTargetingData = (adUnits, moduleConfig, userConsent, auction) => { // Extract `adserverTargeting` and `instance` from the module configuration - const {adserverTargeting, instance} = parseConfig(moduleConfig); + const { adserverTargeting, instance } = parseConfig(moduleConfig); logMessage('Ad Server targeting: ', adserverTargeting); if (!adserverTargeting) { diff --git a/modules/optidigitalBidAdapter.js b/modules/optidigitalBidAdapter.js index 1330bf2054f..b32a0495c8e 100755 --- a/modules/optidigitalBidAdapter.js +++ b/modules/optidigitalBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {deepAccess, isPlainObject, parseSizesInput} from '../src/utils.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { deepAccess, isPlainObject, parseSizesInput } from '../src/utils.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -63,7 +63,8 @@ export const spec = { imp: validBidRequests.map(bidRequest => buildImp(bidRequest, ortb2)), badv: ortb2.badv || deepAccess(validBidRequests[0], 'params.badv') || [], bcat: ortb2.bcat || deepAccess(validBidRequests[0], 'params.bcat') || [], - bapp: deepAccess(validBidRequests[0], 'params.bapp') || [] + bapp: deepAccess(validBidRequests[0], 'params.bapp') || [], + device: ortb2.device || {} } if (validBidRequests[0].auctionId) { @@ -82,10 +83,14 @@ export const spec = { const gdpr = deepAccess(bidderRequest, 'gdprConsent'); if (bidderRequest && gdpr) { const isConsentString = typeof gdpr.consentString === 'string'; + const isGdprApplies = typeof gdpr.gdprApplies === 'boolean'; payload.gdpr = { consent: isConsentString ? gdpr.consentString : '', - required: true + required: isGdprApplies ? gdpr.gdprApplies : false }; + if (gdpr?.addtlConsent) { + payload.gdpr.addtlConsent = gdpr.addtlConsent; + } } if (bidderRequest && !gdpr) { payload.gdpr = { @@ -120,10 +125,16 @@ export const spec = { } } + const ortb2SiteKeywords = (bidderRequest?.ortb2?.site?.keywords || '')?.split(',').map(k => k.trim()).filter(k => k !== '').join(','); + if (ortb2SiteKeywords) { + payload.site = payload.site || {}; + payload.site.keywords = ortb2SiteKeywords; + } + const payloadObject = JSON.stringify(payload); return { method: 'POST', - url: ENDPOINT_URL, + url: `${ENDPOINT_URL}/${payload.publisherId}`, data: payloadObject }; }, @@ -230,6 +241,11 @@ function buildImp(bidRequest, ortb2) { imp.battr = battr; } + const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid'); + if (gpid) { + imp.gpid = gpid; + } + return imp; } diff --git a/modules/optoutBidAdapter.js b/modules/optoutBidAdapter.js index 03cd420b0be..0e91112bf49 100644 --- a/modules/optoutBidAdapter.js +++ b/modules/optoutBidAdapter.js @@ -1,7 +1,7 @@ import { deepAccess } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const BIDDER_CODE = 'optout'; const GVLID = 227; diff --git a/modules/orbitsoftBidAdapter.js b/modules/orbitsoftBidAdapter.js index 7ae2195294d..94648f92032 100644 --- a/modules/orbitsoftBidAdapter.js +++ b/modules/orbitsoftBidAdapter.js @@ -1,6 +1,6 @@ import * as utils from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getBidIdParameter} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getBidIdParameter } from '../src/utils.js'; const BIDDER_CODE = 'orbitsoft'; const styleParamsMap = { @@ -98,7 +98,7 @@ export const spec = { method: 'POST', url: requestUrl, data: requestData, - options: {withCredentials: false}, + options: { withCredentials: false }, bidRequest: bidRequest }); } diff --git a/modules/otmBidAdapter.js b/modules/otmBidAdapter.js index 7d4049e3054..4f9928b8323 100644 --- a/modules/otmBidAdapter.js +++ b/modules/otmBidAdapter.js @@ -20,7 +20,7 @@ export const spec = { code: BIDDER_CODE, url: OTM_BID_URL, - supportedMediaTypes: [ BANNER ], + supportedMediaTypes: [BANNER], /** * Determines whether or not the given bid request is valid. diff --git a/modules/outbrainBidAdapter.js b/modules/outbrainBidAdapter.js index f04ce0886d8..1b08f326c32 100644 --- a/modules/outbrainBidAdapter.js +++ b/modules/outbrainBidAdapter.js @@ -1,15 +1,15 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; -import {OUTSTREAM} from '../src/video.js'; -import {_map, deepAccess, deepSetValue, logWarn, replaceAuctionPrice, setOnAny, parseGPTSingleSizeArrayToRtbSize, isPlainObject} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {Renderer} from '../src/Renderer.js'; +import { OUTSTREAM } from '../src/video.js'; +import { _map, deepAccess, deepSetValue, logWarn, replaceAuctionPrice, setOnAny, parseGPTSingleSizeArrayToRtbSize, isPlainObject } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { Renderer } from '../src/Renderer.js'; const BIDDER_CODE = 'outbrain'; const GVLID = 164; @@ -29,12 +29,12 @@ const NATIVE_ASSET_IDS = Object.entries(NATIVE_PARAMS).reduce((acc, [key, value] const OUTSTREAM_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; const OB_USER_TOKEN_KEY = 'OB-USER-TOKEN'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, gvlid: GVLID, - supportedMediaTypes: [ NATIVE, BANNER, VIDEO ], + supportedMediaTypes: [NATIVE, BANNER, VIDEO], isBidRequestValid: (bid) => { if (typeof bid.params !== 'object') { return false; diff --git a/modules/oxxionAnalyticsAdapter.js b/modules/oxxionAnalyticsAdapter.js index 63776f43a40..223634d28f0 100644 --- a/modules/oxxionAnalyticsAdapter.js +++ b/modules/oxxionAnalyticsAdapter.js @@ -196,7 +196,7 @@ function handleBidWon(args) { args['cpmIncrement'] = increment; args['referer'] = encodeURIComponent(getRefererInfo().page || getRefererInfo().topmostLocation); if (typeof saveEvents.bidRequested === 'object' && saveEvents.bidRequested.length > 0 && saveEvents.bidRequested[0].gdprConsent) { args.gdpr = saveEvents.bidRequested[0].gdprConsent; } - ajax(endpoint + '.oxxion.io/analytics/bid_won', null, JSON.stringify(args), {method: 'POST', withCredentials: true}); + ajax(endpoint + '.oxxion.io/analytics/bid_won', null, JSON.stringify(args), { method: 'POST', withCredentials: true }); } function handleAuctionEnd() { @@ -208,16 +208,16 @@ function handleAuctionEnd() { const tmpId = bidResponse['originalBidder'] + '_' + bidResponse['creativeId']; if (list.includes(tmpId) && !alreadyCalled.includes(tmpId)) { alreadyCalled.push(tmpId); - ajax(endpoint + '.oxxion.io/analytics/creatives', null, JSON.stringify(bidResponse), {method: 'POST', withCredentials: true}); + ajax(endpoint + '.oxxion.io/analytics/creatives', null, JSON.stringify(bidResponse), { method: 'POST', withCredentials: true }); } }); } allEvents = {}; - }, JSON.stringify(auctionEnd), {method: 'POST', withCredentials: true}); + }, JSON.stringify(auctionEnd), { method: 'POST', withCredentials: true }); auctionEnd = {}; } -const oxxionAnalytics = Object.assign(adapter({url, analyticsType}), { +const oxxionAnalytics = Object.assign(adapter({ url, analyticsType }), { track({ eventType, args diff --git a/modules/oxxionRtdProvider.js b/modules/oxxionRtdProvider.js index 238a1f4d6eb..a522d507f27 100644 --- a/modules/oxxionRtdProvider.js +++ b/modules/oxxionRtdProvider.js @@ -46,7 +46,7 @@ function getAdUnits(reqBidsConfigObj, callback, config, userConsent) { [reqBidsConfigObj.adUnits, filteredBids] = getFilteredAdUnitsOnBidRates(bidsRateInterests, reqBidsConfigObj.adUnits, config.params, true); } if (filteredBids.length > 0) { - getPromisifiedAjax('https://' + config.params.domain + '.oxxion.io/analytics/request_rejecteds', JSON.stringify({'bids': filteredBids, 'gdpr': gdpr}), { + getPromisifiedAjax('https://' + config.params.domain + '.oxxion.io/analytics/request_rejecteds', JSON.stringify({ 'bids': filteredBids, 'gdpr': gdpr }), { method: 'POST', withCredentials: true }); @@ -55,7 +55,7 @@ function getAdUnits(reqBidsConfigObj, callback, config, userConsent) { const timeToRun = new Date() - moduleStarted; logInfo(LOG_PREFIX + ' time to run: ' + timeToRun); if (getRandomNumber(50) === 1) { - ajax('https://' + config.params.domain + '.oxxion.io/ova/time', null, JSON.stringify({'duration': timeToRun, 'auctionId': reqBidsConfigObj.auctionId}), {method: 'POST', withCredentials: true}); + ajax('https://' + config.params.domain + '.oxxion.io/ova/time', null, JSON.stringify({ 'duration': timeToRun, 'auctionId': reqBidsConfigObj.auctionId }), { method: 'POST', withCredentials: true }); } }).catch(error => logError(LOG_PREFIX, 'bidInterestError', error)); } diff --git a/modules/ozoneBidAdapter.js b/modules/ozoneBidAdapter.js index e804eef164e..1d7aff59ee2 100644 --- a/modules/ozoneBidAdapter.js +++ b/modules/ozoneBidAdapter.js @@ -11,11 +11,11 @@ import { } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {getPriceBucketString} from '../src/cpmBucketManager.js'; +import { config } from '../src/config.js'; +import { getPriceBucketString } from '../src/cpmBucketManager.js'; import { Renderer } from '../src/Renderer.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {toOrtb25} from '../libraries/ortb2.5Translator/translator.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { toOrtb25 } from '../libraries/ortb2.5Translator/translator.js'; const BIDDER_CODE = 'ozone'; const ORIGIN = 'https://elb.the-ozone-project.com'; const AUCTIONURI = '/openrtb2/auction'; @@ -28,8 +28,8 @@ export const spec = { version: OZONEVERSION, code: BIDDER_CODE, supportedMediaTypes: [VIDEO, BANNER], - cookieSyncBag: {publisherId: null, siteId: null, userIdObject: {}}, - propertyBag: {pageId: null, buildRequestsStart: 0, buildRequestsEnd: 0}, + cookieSyncBag: { publisherId: null, siteId: null, userIdObject: {} }, + propertyBag: { pageId: null, buildRequestsStart: 0, buildRequestsEnd: 0 }, getAuctionUrl() { const ep = config.getConfig('ozone.endpointOverride') || {}; if (ep.auctionUrl) return ep.auctionUrl; @@ -138,7 +138,7 @@ export const spec = { return []; } const fledgeEnabled = !!bidderRequest.fledgeEnabled; - let htmlParams = {'publisherId': '', 'siteId': ''}; + let htmlParams = { 'publisherId': '', 'siteId': '' }; if (validBidRequests.length > 0) { Object.assign(this.cookieSyncBag.userIdObject, this.findAllUserIdsFromEids(validBidRequests[0])); this.cookieSyncBag.siteId = deepAccess(validBidRequests[0], 'params.siteId'); @@ -148,9 +148,9 @@ export const spec = { logInfo('cookie sync bag', this.cookieSyncBag); let singleRequest = config.getConfig('ozone.singleRequest'); singleRequest = singleRequest !== false; - const ozoneRequest = {site: {}, regs: {}, user: {}}; + const ozoneRequest = { site: {}, regs: {}, user: {} }; const fpd = deepAccess(bidderRequest, 'ortb2', {}); - const fpdPruned = this.pruneToExtPaths(fpd, {maxTestDepth: 2}); + const fpdPruned = this.pruneToExtPaths(fpd, { maxTestDepth: 2 }); logInfo('got ortb2 fpd: ', fpd); logInfo('got ortb2 fpdPruned: ', fpdPruned); logInfo('going to assign the pruned (ext only) FPD ortb2 object to ozoneRequest, wholesale'); @@ -159,7 +159,7 @@ export const spec = { const getParams = this.getGetParametersAsObject(); const wlOztestmodeKey = 'oztestmode'; const isTestMode = getParams[wlOztestmodeKey] || null; - mergeDeep(ozoneRequest, {device: bidderRequest?.ortb2?.device || {}}); + mergeDeep(ozoneRequest, { device: bidderRequest?.ortb2?.device || {} }); const placementIdOverrideFromGetParam = this.getPlacementIdOverrideFromGetParam(); let schain = null; var auctionId = deepAccess(validBidRequests, '0.ortb2.source.tid'); @@ -168,7 +168,7 @@ export const spec = { } const tosendtags = validBidRequests.map(ozoneBidRequest => { var obj = {}; - let prunedImp = this.pruneToExtPaths(ozoneBidRequest.ortb2Imp, {maxTestDepth: 2}); + let prunedImp = this.pruneToExtPaths(ozoneBidRequest.ortb2Imp, { maxTestDepth: 2 }); logInfo('merging into bid[] from pruned ozoneBidRequest.ortb2Imp (this includes adunits ortb2imp and gpid & tid from gptPreAuction if included', prunedImp); mergeDeep(obj, prunedImp); const placementId = placementIdOverrideFromGetParam || this.getPlacementId(ozoneBidRequest); @@ -229,12 +229,12 @@ export const spec = { w: arrBannerSizes[0][0] || 0, h: arrBannerSizes[0][1] || 0, format: arrBannerSizes.map(s => { - return {w: s[0], h: s[1]}; + return { w: s[0], h: s[1] }; }) }; } obj.placementId = placementId; - mergeDeep(obj, {ext: {prebid: {'storedrequest': {'id': placementId}}}}); + mergeDeep(obj, { ext: { prebid: { 'storedrequest': { 'id': placementId } } } }); obj.ext[bidderKey] = obj.ext[bidderKey] || {}; obj.ext[bidderKey].adUnitCode = ozoneBidRequest.adUnitCode; if (ozoneBidRequest.params.hasOwnProperty('customData')) { @@ -256,7 +256,7 @@ export const spec = { obj.ext[bidderKey].customData[i]['targeting'][wlOztestmodeKey] = isTestMode; } } else { - obj.ext[bidderKey].customData = [{'settings': {}, 'targeting': {}}]; + obj.ext[bidderKey].customData = [{ 'settings': {}, 'targeting': {} }]; obj.ext[bidderKey].customData[0].targeting[wlOztestmodeKey] = isTestMode; } } @@ -311,7 +311,7 @@ export const spec = { } const userExtEids = deepAccess(validBidRequests, '0.userIdAsEids', []); mergeDeep(ozoneRequest.site, { - 'publisher': {'id': htmlParams.publisherId}, + 'publisher': { 'id': htmlParams.publisherId }, 'page': getRefererInfo().page, 'id': htmlParams.siteId }); @@ -319,7 +319,7 @@ export const spec = { if (bidderRequest && bidderRequest.gdprConsent) { logInfo('ADDING GDPR'); const apiVersion = deepAccess(bidderRequest, 'gdprConsent.apiVersion', 1); - mergeDeep(ozoneRequest.regs, {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, apiVersion: apiVersion}}); + mergeDeep(ozoneRequest.regs, { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0, apiVersion: apiVersion } }); if (bidderRequest.gdprConsent.gdprApplies) { deepSetValue(ozoneRequest, 'user.ext.consent', bidderRequest.gdprConsent.consentString); } else { @@ -353,12 +353,12 @@ export const spec = { const arrRet = []; for (let i = 0; i < tosendtags.length; i += batchRequestsVal) { ozoneRequest.id = generateUUID(); - mergeDeep(ozoneRequest, {user: {ext: {eids: userExtEids}}}); + mergeDeep(ozoneRequest, { user: { ext: { eids: userExtEids } } }); if (auctionId) { deepSetValue(ozoneRequest, 'source.tid', auctionId); } ozoneRequest.imp = tosendtags.slice(i, i + batchRequestsVal); - mergeDeep(ozoneRequest, {ext: extObj}); + mergeDeep(ozoneRequest, { ext: extObj }); toOrtb25(ozoneRequest); if (ozoneRequest.imp.length > 0) { arrRet.push({ @@ -377,9 +377,9 @@ export const spec = { logInfo('single request starting'); ozoneRequest.id = generateUUID(); ozoneRequest.imp = tosendtags; - mergeDeep(ozoneRequest, {ext: extObj}); + mergeDeep(ozoneRequest, { ext: extObj }); toOrtb25(ozoneRequest); - mergeDeep(ozoneRequest, {user: {ext: {eids: userExtEids}}}); + mergeDeep(ozoneRequest, { user: { ext: { eids: userExtEids } } }); if (auctionId) { deepSetValue(ozoneRequest, 'source.tid', auctionId); } @@ -398,8 +398,8 @@ export const spec = { const ozoneRequestSingle = Object.assign({}, ozoneRequest); ozoneRequestSingle.id = generateUUID(); ozoneRequestSingle.imp = [imp]; - mergeDeep(ozoneRequestSingle, {ext: extObj}); - mergeDeep(ozoneRequestSingle, {user: {ext: {eids: userExtEids}}}); + mergeDeep(ozoneRequestSingle, { ext: extObj }); + mergeDeep(ozoneRequestSingle, { user: { ext: { eids: userExtEids } } }); if (auctionId) { deepSetValue(ozoneRequestSingle, 'source.tid', auctionId); } @@ -424,13 +424,13 @@ export const spec = { logInfo('getFloorObjectForAuction mediaTypesSizes : ', mediaTypesSizes); const ret = {}; if (mediaTypesSizes.banner) { - ret.banner = bidRequestRef.getFloor({mediaType: 'banner', currency: 'USD', size: mediaTypesSizes.banner[0]}); + ret.banner = bidRequestRef.getFloor({ mediaType: 'banner', currency: 'USD', size: mediaTypesSizes.banner[0] }); } if (mediaTypesSizes.video) { - ret.video = bidRequestRef.getFloor({mediaType: 'video', currency: 'USD', size: mediaTypesSizes.video[0]}); + ret.video = bidRequestRef.getFloor({ mediaType: 'video', currency: 'USD', size: mediaTypesSizes.video[0] }); } if (mediaTypesSizes.native) { - ret.native = bidRequestRef.getFloor({mediaType: 'native', currency: 'USD', size: mediaTypesSizes.native[0]}); + ret.native = bidRequestRef.getFloor({ mediaType: 'native', currency: 'USD', size: mediaTypesSizes.native[0] }); } logInfo('getFloorObjectForAuction returning : ', deepClone(ret)); return ret; @@ -468,9 +468,9 @@ export const spec = { for (let j = 0; j < sb.bid.length; j++) { const thisRequestBid = this.getBidRequestForBidId(sb.bid[j].impid, request.bidderRequest.bids); logInfo(`seatbid:${i}, bid:${j} Going to set default w h for seatbid/bidRequest`, sb.bid[j], thisRequestBid); - const {defaultWidth, defaultHeight} = defaultSize(thisRequestBid); + const { defaultWidth, defaultHeight } = defaultSize(thisRequestBid); const thisBid = ozoneAddStandardProperties(sb.bid[j], defaultWidth, defaultHeight); - thisBid.meta = {advertiserDomains: thisBid.adomain || []}; + thisBid.meta = { advertiserDomains: thisBid.adomain || [] }; let videoContext = null; let isVideo = false; const bidType = deepAccess(thisBid, 'ext.prebid.type'); @@ -544,7 +544,7 @@ export const spec = { logInfo(perBidInfo); } } - let {seat: winningSeat, bid: winningBid} = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid); + let { seat: winningSeat, bid: winningBid } = ozoneGetWinnerForRequestBid(thisBid.bidId, serverResponse.seatbid); winningBid = ozoneAddStandardProperties(winningBid, defaultWidth, defaultHeight); adserverTargeting[prefix + '_auc_id'] = String(aucId); adserverTargeting[prefix + '_winner'] = String(winningSeat); @@ -603,7 +603,7 @@ export const spec = { var ret = []; for (let i = 0; i < seatbid.length; i++) { const sb = seatbid[i]; - var retSeatbid = {'seat': sb.seat, 'bid': []}; + var retSeatbid = { 'seat': sb.seat, 'bid': [] }; var bidIds = []; for (let j = 0; j < sb.bid.length; j++) { var candidate = sb.bid[j]; @@ -727,7 +727,7 @@ export const spec = { return this.propertyBag.pageId; }, unpackVideoConfigIntoIABformat(videoConfig, childConfig) { - let ret = {'ext': {}}; + let ret = { 'ext': {} }; ret = this._unpackVideoConfigIntoIABformat(ret, videoConfig); ret = this._unpackVideoConfigIntoIABformat(ret, childConfig); return ret; @@ -886,7 +886,7 @@ export function ozoneGetWinnerForRequestBid(requestBidId, serverResponseSeatBid) } } } - return {'seat': winningSeat, 'bid': thisBidWinner}; + return { 'seat': winningSeat, 'bid': thisBidWinner }; } export function ozoneGetAllBidsForBidId(matchBidId, serverResponseSeatBid, defaultWidth, defaultHeight) { const objBids = {}; @@ -926,7 +926,7 @@ export function getRoundedBid(price, mediaType) { key = 'custom'; } } - const mapping = {medium: 'med', custom: 'custom', high: 'high', low: 'low', dense: 'dense'}; + const mapping = { medium: 'med', custom: 'custom', high: 'high', low: 'low', dense: 'dense' }; const priceStrings = getPriceBucketString(price, buckets, config.getConfig('currency.granularityMultiplier')); logInfo('getRoundedBid price:', price, 'mediaType:', mediaType, 'bucketKey:', key); return priceStrings[mapping[key] || 'auto']; @@ -961,7 +961,7 @@ export function getWidthAndHeightFromVideoObject(objVideo) { logError('getWidthAndHeightFromVideoObject found playerSize with length of ' + playerSize.length + '. This is totally wrong - cannot continue.'); return null; } - return ({'w': playerSize[0], 'h': playerSize[1]}); + return ({ 'w': playerSize[0], 'h': playerSize[1] }); } function getPlayerSizeFromObject(objVideo) { logInfo('getPlayerSizeFromObject received object', objVideo); diff --git a/modules/paapi.js b/modules/paapi.js index e67b24bdcfc..e7e00b3f4e8 100644 --- a/modules/paapi.js +++ b/modules/paapi.js @@ -1,8 +1,8 @@ /** * Collect PAAPI component auction configs from bid adapters and make them available through `pbjs.getPAAPIConfig()` */ -import {config} from '../src/config.js'; -import {getHook, hook, module} from '../src/hook.js'; +import { config } from '../src/config.js'; +import { getHook, hook, module } from '../src/hook.js'; import { deepAccess, deepEqual, @@ -13,16 +13,16 @@ import { mergeDeep, sizesToSizeTuples } from '../src/utils.js'; -import {IMP, PBS, registerOrtbProcessor, RESPONSE} from '../src/pbjsORTB.js'; +import { IMP, PBS, registerOrtbProcessor, RESPONSE } from '../src/pbjsORTB.js'; import * as events from '../src/events.js'; -import {EVENTS} from '../src/constants.js'; -import {currencyCompare} from '../libraries/currencyUtils/currency.js'; -import {keyCompare, maximum, minimum} from '../src/utils/reducers.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {auctionStore} from '../libraries/weakStore/weakStore.js'; -import {adapterMetrics, guardTids} from '../src/adapters/bidderFactory.js'; -import {defer, PbPromise} from '../src/utils/promise.js'; -import {auctionManager} from '../src/auctionManager.js'; +import { EVENTS } from '../src/constants.js'; +import { currencyCompare } from '../libraries/currencyUtils/currency.js'; +import { keyCompare, maximum, minimum } from '../src/utils/reducers.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { auctionStore } from '../libraries/weakStore/weakStore.js'; +import { adapterMetrics, guardTids } from '../src/adapters/bidderFactory.js'; +import { defer, PbPromise } from '../src/utils/promise.js'; +import { auctionManager } from '../src/auctionManager.js'; const MODULE = 'PAAPI'; @@ -92,12 +92,12 @@ function attachHandlers() { } function detachHandlers() { - getHook('addPaapiConfig').getHooks({hook: addPaapiConfigHook}).remove(); - getHook('makeBidRequests').getHooks({hook: addPaapiData}).remove(); - getHook('makeBidRequests').getHooks({hook: markForFledge}).remove(); - getHook('processBidderRequests').getHooks({hook: parallelPaapiProcessing}).remove(); - getHook('processBidderRequests').getHooks({hook: buildPAAPIParams}).remove(); - getHook('processBidderRequests').getHooks({hook: adAuctionHeadersHook}).remove(); + getHook('addPaapiConfig').getHooks({ hook: addPaapiConfigHook }).remove(); + getHook('makeBidRequests').getHooks({ hook: addPaapiData }).remove(); + getHook('makeBidRequests').getHooks({ hook: markForFledge }).remove(); + getHook('processBidderRequests').getHooks({ hook: parallelPaapiProcessing }).remove(); + getHook('processBidderRequests').getHooks({ hook: buildPAAPIParams }).remove(); + getHook('processBidderRequests').getHooks({ hook: adAuctionHeadersHook }).remove(); events.off(EVENTS.AUCTION_INIT, onAuctionInit); events.off(EVENTS.AUCTION_END, onAuctionEnd); } @@ -161,7 +161,7 @@ export function buyersToAuctionConfigs(igbRequests, merge = mergeBuyers, config }); } -function onAuctionEnd({auctionId, bidsReceived, bidderRequests, adUnitCodes, adUnits}) { +function onAuctionEnd({ auctionId, bidsReceived, bidderRequests, adUnitCodes, adUnits }) { const adUnitsByCode = Object.fromEntries(adUnits?.map(au => [au.code, au]) || []); const allReqs = bidderRequests?.flatMap(br => br.bids); const paapiConfigs = configsForAuction(auctionId); @@ -177,7 +177,7 @@ function onAuctionEnd({auctionId, bidsReceived, bidderRequests, adUnitCodes, adU if (pendingConfigs && pendingBuyers) { Object.entries(pendingBuyers).forEach(([adUnitCode, igbRequests]) => { - buyersToAuctionConfigs(igbRequests).forEach(([{bidder}, auctionConfig]) => append(pendingConfigs, adUnitCode, {id: getComponentSellerConfigId(bidder), config: auctionConfig})) + buyersToAuctionConfigs(igbRequests).forEach(([{ bidder }, auctionConfig]) => append(pendingConfigs, adUnitCode, { id: getComponentSellerConfigId(bidder), config: auctionConfig })) }) } @@ -197,14 +197,14 @@ function onAuctionEnd({auctionId, bidsReceived, bidderRequests, adUnitCodes, adU const configsById = {}; Object.entries(pendingConfigs || {}).forEach(([adUnitCode, auctionConfigs]) => { - auctionConfigs.forEach(({id, config}) => append(configsById, id, { + auctionConfigs.forEach(({ id, config }) => append(configsById, id, { adUnitCode, config: mergeDeep({}, signals[adUnitCode], config) })); }); function resolveSignals(signals, deferrals) { - Object.entries(deferrals).forEach(([signal, {resolve, default: defaultValue}]) => { + Object.entries(deferrals).forEach(([signal, { resolve, default: defaultValue }]) => { let value = signals.hasOwnProperty(signal) ? signals[signal] : null; if (value == null && defaultValue == null) { value = undefined; @@ -217,14 +217,14 @@ function onAuctionEnd({auctionId, bidsReceived, bidderRequests, adUnitCodes, adU }) } - Object.entries(deferredConfigs).forEach(([adUnitCode, {top, components}]) => { + Object.entries(deferredConfigs).forEach(([adUnitCode, { top, components }]) => { resolveSignals(signals[adUnitCode], top); - Object.entries(components).forEach(([configId, {deferrals}]) => { + Object.entries(components).forEach(([configId, { deferrals }]) => { const matchingConfigs = configsById.hasOwnProperty(configId) ? configsById[configId] : []; if (matchingConfigs.length > 1) { logWarn(`Received multiple PAAPI configs for the same bidder and seller (${configId}), active PAAPI auctions will only see the first`); } - const {config} = matchingConfigs.shift() ?? {config: {...signals[adUnitCode]}} + const { config } = matchingConfigs.shift() ?? { config: { ...signals[adUnitCode] } } resolveSignals(config, deferrals); }) }); @@ -236,7 +236,7 @@ function onAuctionEnd({auctionId, bidsReceived, bidderRequests, adUnitCodes, adU logError(`Received PAAPI configs after PAAPI auctions were already started in parallel with their contextual auction`, newConfigs) } - newConfigs.forEach(({adUnitCode, config}) => { + newConfigs.forEach(({ adUnitCode, config }) => { if (paapiConfigs[adUnitCode] == null) { paapiConfigs[adUnitCode] = { ...signals[adUnitCode], @@ -256,7 +256,7 @@ function append(target, key, value) { target[key].push(value); } -function setFPD(target, {ortb2, ortb2Imp}) { +function setFPD(target, { ortb2, ortb2Imp }) { ortb2 != null && deepSetValue(target, 'prebid.ortb2', mergeDeep({}, ortb2, target.prebid?.ortb2)); ortb2Imp != null && deepSetValue(target, 'prebid.ortb2Imp', mergeDeep({}, ortb2Imp, target.prebid?.ortb2Imp)); return target; @@ -272,7 +272,7 @@ function getComponentSellerConfigId(bidderCode) { export function addPaapiConfigHook(next, request, paapiConfig) { if (getFledgeConfig(config.getCurrentBidder()).enabled) { - const {adUnitCode, auctionId, bidder} = request; + const { adUnitCode, auctionId, bidder } = request; function storePendingData(store, data) { const target = store(auctionId); @@ -283,14 +283,14 @@ export function addPaapiConfigHook(next, request, paapiConfig) { } } - const {config, igb} = paapiConfig; + const { config, igb } = paapiConfig; if (config) { config.auctionSignals = setFPD(config.auctionSignals || {}, request); const pbs = config.perBuyerSignals = config.perBuyerSignals ?? {}; (config.interestGroupBuyers || []).forEach(buyer => { pbs[buyer] = setFPD(pbs[buyer] ?? {}, request); }) - storePendingData(pendingConfigsForAuction, {id: getConfigId(bidder, config.seller), config}); + storePendingData(pendingConfigsForAuction, { id: getConfigId(bidder, config.seller), config }); } if (igb && checkOrigin(igb)) { igb.pbs = setFPD(igb.pbs || {}, request); @@ -381,7 +381,7 @@ export function partitionBuyersByBidder(igbRequests) { * when not specified, the result will contain an entry for every ad unit that was involved in any auction. * @return {{[adUnitCode: string]: string}} */ -function expandFilters({auctionId, adUnitCode} = {}) { +function expandFilters({ auctionId, adUnitCode } = {}) { let adUnitCodes = []; if (adUnitCode == null) { adUnitCodes = Object.keys(latestAuctionForAdUnit); @@ -487,7 +487,7 @@ export function addPaapiData(next, adUnits, ...args) { adUnit.bids.forEach(bidReq => { if (!getFledgeConfig(bidReq.bidder).enabled) { deepSetValue(bidReq, 'ortb2Imp.ext.ae', 0); - bidReq.ortb2Imp.ext.igs = {ae: 0, biddable: 0}; + bidReq.ortb2Imp.ext.igs = { ae: 0, biddable: 0 }; } }) } @@ -501,7 +501,7 @@ export const NAVIGATOR_APIS = ['createAuctionNonce', 'getInterestGroupAdAuctionD export function markForFledge(next, bidderRequests) { if (isFledgeSupported()) { bidderRequests.forEach((bidderReq) => { - const {enabled} = getFledgeConfig(bidderReq.bidderCode); + const { enabled } = getFledgeConfig(bidderReq.bidderCode); Object.assign(bidderReq, { paapi: { enabled, @@ -546,7 +546,7 @@ const validatePartialConfig = (() => { ]; return function (config) { - const invalid = REQUIRED_SYNC_SIGNALS.find(({props, validate}) => props.every(prop => !config.hasOwnProperty(prop) || !config[prop] || !validate(config[prop]))); + const invalid = REQUIRED_SYNC_SIGNALS.find(({ props, validate }) => props.every(prop => !config.hasOwnProperty(prop) || !config[prop] || !validate(config[prop]))); if (invalid) { logError(`Partial PAAPI config has missing or invalid property "${invalid.props[0]}"`, config) return false; @@ -593,7 +593,7 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args function makeDeferrals(defaults = {}) { const promises = {}; const deferrals = Object.fromEntries(ASYNC_SIGNALS.map(signal => { - const def = defer({promiseFactory: (resolver) => new Promise(resolver)}); + const def = defer({ promiseFactory: (resolver) => new Promise(resolver) }); def.default = defaults.hasOwnProperty(signal) ? defaults[signal] : null; promises[signal] = def.promise; return [signal, def] @@ -601,7 +601,7 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args return [deferrals, promises]; } - const {auctionId, paapi: {enabled, componentSeller} = {}} = bidderRequest; + const { auctionId, paapi: { enabled, componentSeller } = {} } = bidderRequest; const auctionConfigs = configsForAuction(auctionId); bids.map(bid => bid.adUnitCode).forEach(adUnitCode => { latestAuctionForAdUnit[adUnitCode] = auctionId; @@ -613,10 +613,10 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args if (enabled && spec.buildPAAPIConfigs) { const partialConfigs = callAdapterApi(spec, 'buildPAAPIConfigs', bids, bidderRequest) const requestsById = Object.fromEntries(bids.map(bid => [bid.bidId, bid])); - (partialConfigs ?? []).forEach(({bidId, config, igb}) => { + (partialConfigs ?? []).forEach(({ bidId, config, igb }) => { const bidRequest = requestsById.hasOwnProperty(bidId) && requestsById[bidId]; if (!bidRequest) { - logError(`Received partial PAAPI config for unknown bidId`, {bidId, config}); + logError(`Received partial PAAPI config for unknown bidId`, { bidId, config }); } else { const adUnitCode = bidRequest.adUnitCode; latestAuctionForAdUnit[adUnitCode] = auctionId; @@ -655,7 +655,7 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args ...promises } deferredConfig.auctionConfig.componentAuctions.push(auctionConfig) - deferredConfig.components[configId] = {auctionConfig, deferrals}; + deferredConfig.components[configId] = { auctionConfig, deferrals }; } } if (componentSeller && igb && checkOrigin(igb)) { @@ -663,12 +663,12 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args const deferredConfig = getDeferredConfig(); const partialConfig = buyersToAuctionConfigs([[bidRequest, igb]])[0][1]; if (deferredConfig.components.hasOwnProperty(configId)) { - const {auctionConfig, deferrals} = deferredConfig.components[configId]; + const { auctionConfig, deferrals } = deferredConfig.components[configId]; if (!auctionConfig.interestGroupBuyers.includes(igb.origin)) { const immediate = {}; Object.entries(partialConfig).forEach(([key, value]) => { if (deferrals.hasOwnProperty(key)) { - mergeDeep(deferrals[key], {default: value}); + mergeDeep(deferrals[key], { default: value }); } else { immediate[key] = value; } @@ -684,7 +684,7 @@ export function parallelPaapiProcessing(next, spec, bids, bidderRequest, ...args ...getStaticSignals(bidRequest), ...promises, } - deferredConfig.components[configId] = {auctionConfig, deferrals}; + deferredConfig.components[configId] = { auctionConfig, deferrals }; deferredConfig.auctionConfig.componentAuctions.push(auctionConfig); } } @@ -720,9 +720,9 @@ export function buildPAAPIParams(next, spec, bids, bidderRequest, ...args) { } } -export function onAuctionInit({auctionId}) { +export function onAuctionInit({ auctionId }) { if (moduleConfig.parallel) { - auctionManager.index.getAuction({auctionId}).requestsDone.then(() => { + auctionManager.index.getAuction({ auctionId }).requestsDone.then(() => { if (Object.keys(deferredConfigsForAuction(auctionId)).length > 0) { submodules.forEach(submod => submod.onAuctionConfig?.(auctionId, configsForAuction(auctionId))); } @@ -737,7 +737,7 @@ export function setImpExtAe(imp, bidRequest, context) { } } -registerOrtbProcessor({type: IMP, name: 'impExtAe', fn: setImpExtAe}); +registerOrtbProcessor({ type: IMP, name: 'impExtAe', fn: setImpExtAe }); export function parseExtIgi(response, ortbResponse, context) { paapiResponseParser( @@ -783,8 +783,8 @@ export function parseExtPrebidFledge(response, ortbResponse, context) { ) } -registerOrtbProcessor({type: RESPONSE, name: 'extPrebidFledge', fn: parseExtPrebidFledge, dialects: [PBS]}); -registerOrtbProcessor({type: RESPONSE, name: 'extIgiIgs', fn: parseExtIgi}); +registerOrtbProcessor({ type: RESPONSE, name: 'extPrebidFledge', fn: parseExtPrebidFledge, dialects: [PBS] }); +registerOrtbProcessor({ type: RESPONSE, name: 'extIgiIgs', fn: parseExtIgi }); // ...then, make them available in the adapter's response. This is the client side version, for which the // interpretResponse api is {fledgeAuctionConfigs: [{bidId, config}]} diff --git a/modules/paapiForGpt.js b/modules/paapiForGpt.js index 363c83ada03..a7f1dc609f4 100644 --- a/modules/paapiForGpt.js +++ b/modules/paapiForGpt.js @@ -1,13 +1,13 @@ /** * GPT-specific slot configuration logic for PAAPI. */ -import {getHook, submodule} from '../src/hook.js'; -import {deepAccess, logInfo, logWarn, sizeTupleToSizeString} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { getHook, submodule } from '../src/hook.js'; +import { deepAccess, logInfo, logWarn, sizeTupleToSizeString } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js'; -import {keyCompare} from '../src/utils/reducers.js'; -import {getGPTSlotsForAdUnits, targeting} from '../src/targeting.js'; +import { keyCompare } from '../src/utils/reducers.js'; +import { getGPTSlotsForAdUnits, targeting } from '../src/targeting.js'; const MODULE = 'paapiForGpt'; @@ -18,7 +18,7 @@ config.getConfig('paapi', (cfg) => { logInfo(MODULE, 'enabling PAAPI configuration with setTargetingForGPTAsync') targeting.setTargetingForGPT.before(setTargetingHook); } else { - targeting.setTargetingForGPT.getHooks({hook: setTargetingHook}).remove(); + targeting.setTargetingForGPT.getHooks({ hook: setTargetingHook }).remove(); } }); @@ -26,7 +26,7 @@ export function setTargetingHookFactory(setPaapiConfig = getGlobal().setPAAPICon return function(next, adUnit, customSlotMatching) { const adUnitCodes = Array.isArray(adUnit) ? adUnit : [adUnit] adUnitCodes - .map(adUnitCode => adUnitCode == null ? undefined : {adUnitCode}) + .map(adUnitCode => adUnitCode == null ? undefined : { adUnitCode }) .forEach(filters => setPaapiConfig(filters, customSlotMatching)) next(adUnit, customSlotMatching); } @@ -49,10 +49,10 @@ export function slotConfigurator() { } Object.keys(previous).length ? PREVIOUSLY_SET[adUnitCode] = previous : delete PREVIOUSLY_SET[adUnitCode]; const componentAuction = Object.entries(configsBySeller) - .map(([configKey, auctionConfig]) => ({configKey, auctionConfig})); + .map(([configKey, auctionConfig]) => ({ configKey, auctionConfig })); if (componentAuction.length > 0) { gptSlots.forEach(gptSlot => { - gptSlot.setConfig({componentAuction}); + gptSlot.setConfig({ componentAuction }); logInfo(MODULE, `register component auction configs for: ${adUnitCode}: ${gptSlot.getAdUnitPath()}`, auctionConfigs); // reference https://developers.google.com/publisher-tag/reference#googletag.config.ComponentAuctionConfig }); diff --git a/modules/padsquadBidAdapter.js b/modules/padsquadBidAdapter.js index 48471fc98e3..0a6afd6b448 100644 --- a/modules/padsquadBidAdapter.js +++ b/modules/padsquadBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { deepAccess, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://x.padsquad.com/auction'; @@ -57,8 +57,8 @@ export const spec = { // apply gdpr if (bidderRequest.gdprConsent) { - openrtbRequest.regs = {ext: {gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0}}; - openrtbRequest.user = {ext: {consent: bidderRequest.gdprConsent.consentString}}; + openrtbRequest.regs = { ext: { gdpr: bidderRequest.gdprConsent.gdprApplies ? 1 : 0 } }; + openrtbRequest.user = { ext: { consent: bidderRequest.gdprConsent.consentString } }; } const payloadString = JSON.stringify(openrtbRequest); diff --git a/modules/pairIdSystem.js b/modules/pairIdSystem.js index 4b1e287e957..fe4e761740e 100644 --- a/modules/pairIdSystem.js +++ b/modules/pairIdSystem.js @@ -6,9 +6,9 @@ */ import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js' +import { getStorageManager } from '../src/storageManager.js' import { logInfo } from '../src/utils.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -18,7 +18,7 @@ const MODULE_NAME = 'pairId'; const PAIR_ID_KEY = 'pairId'; const DEFAULT_LIVERAMP_PAIR_ID_KEY = '_lr_pairId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function pairIdFromLocalStorage(key) { return storage.localStorageIsEnabled() ? storage.getDataFromLocalStorage(key) : null; @@ -47,7 +47,7 @@ export const pairIdSubmodule = { * @returns {{pairId:string} | undefined } */ decode(value) { - return value && Array.isArray(value) ? {'pairId': value} : undefined + return value && Array.isArray(value) ? { 'pairId': value } : undefined }, /** * Performs action to obtain ID and return a value in the callback's response argument. @@ -98,7 +98,7 @@ export const pairIdSubmodule = { logInfo('PairId not found.') return undefined; } - return {'id': ids}; + return { 'id': ids }; }, eids: { 'pairId': { diff --git a/modules/pangleBidAdapter.js b/modules/pangleBidAdapter.js index c22a44687a2..a92b2a13910 100644 --- a/modules/pangleBidAdapter.js +++ b/modules/pangleBidAdapter.js @@ -114,7 +114,7 @@ const converter = ortbConverter({ context.mediaType = VIDEO; bidResponse = buildBidResponse(bid, context); if (bidRequest.mediaTypes.video?.context === 'outstream') { - const renderer = Renderer.install({id: bid.bidId, url: OUTSTREAM_RENDERER_URL, adUnitCode: bid.adUnitCode}); + const renderer = Renderer.install({ id: bid.bidId, url: OUTSTREAM_RENDERER_URL, adUnitCode: bid.adUnitCode }); renderer.setRender(renderOutstream); bidResponse.renderer = renderer; } diff --git a/modules/panxoRtdProvider.js b/modules/panxoRtdProvider.js new file mode 100644 index 00000000000..5865106e564 --- /dev/null +++ b/modules/panxoRtdProvider.js @@ -0,0 +1,227 @@ +/** + * This module adds Panxo AI traffic classification to the real time data module. + * + * The {@link module:modules/realTimeData} module is required. + * The module injects the Panxo signal collection script, enriching bid requests + * with AI traffic classification data and contextual signals for improved targeting. + * @module modules/panxoRtdProvider + * @requires module:modules/realTimeData + */ + +import { submodule } from '../src/hook.js'; +import { + prefixLog, + mergeDeep, + generateUUID, + getWindowSelf, +} from '../src/utils.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { loadExternalScript } from '../src/adloader.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; + +/** + * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule + * @typedef {import('../modules/rtdModule/index.js').SubmoduleConfig} SubmoduleConfig + * @typedef {import('../modules/rtdModule/index.js').UserConsentData} UserConsentData + */ + +const SUBMODULE_NAME = 'panxo'; +const SCRIPT_URL = 'https://api.idsequoia.ai/rtd.js'; + +const { logWarn, logError } = prefixLog(`[${SUBMODULE_NAME}]:`); + +/** @type {string} */ +let siteId = ''; + +/** @type {boolean} */ +let verbose = false; + +/** @type {string} */ +let sessionId = ''; + +/** @type {Object} */ +let panxoData = {}; + +/** @type {boolean} */ +let implReady = false; + +/** @type {Array} */ +let pendingCallbacks = []; + +/** + * Submodule registration + */ +function main() { + submodule('realTimeData', /** @type {RtdSubmodule} */ ({ + name: SUBMODULE_NAME, + + init: (config, userConsent) => { + try { + load(config); + return true; + } catch (err) { + logError('init', err.message); + return false; + } + }, + + getBidRequestData: onGetBidRequestData + })); +} + +/** + * Validates configuration and loads the Panxo signal collection script. + * @param {SubmoduleConfig} config + */ +function load(config) { + siteId = config?.params?.siteId || ''; + if (!siteId || typeof siteId !== 'string') { + throw new Error(`The 'siteId' parameter is required and must be a string`); + } + + // siteId is a 16-character hex hash identifying the publisher property + if (!/^[a-f0-9]{16}$/.test(siteId)) { + throw new Error(`The 'siteId' parameter must be a valid 16-character hex identifier`); + } + + // Load/reset the state + verbose = !!config?.params?.verbose; + sessionId = generateUUID(); + panxoData = {}; + implReady = false; + pendingCallbacks = []; + + const refDomain = getRefererInfo().domain || ''; + + // The implementation script uses the session parameter to register + // a bridge API on window['panxo_' + sessionId] + const scriptUrl = `${SCRIPT_URL}?siteId=${siteId}&session=${sessionId}&r=${refDomain}`; + + loadExternalScript(scriptUrl, MODULE_TYPE_RTD, SUBMODULE_NAME, onImplLoaded); +} + +/** + * Callback invoked when the external script finishes loading. + * Establishes the bridge between this RTD submodule and the implementation. + */ +function onImplLoaded() { + const wnd = getWindowSelf(); + const impl = wnd[`panxo_${sessionId}`]; + if (typeof impl !== 'object' || typeof impl.connect !== 'function') { + if (verbose) logWarn('onload', 'Unable to access the implementation script'); + if (!implReady) { + implReady = true; + flushPendingCallbacks(); + } + return; + } + + // Set up the bridge. The callback may be called multiple times as + // more precise signal data becomes available. + impl.connect(getGlobal(), onImplMessage); +} + +/** + * Bridge callback invoked by the implementation script to update signal data. + * When the first signal arrives, flushes any pending auction callbacks so + * the auction can proceed with enriched data. + * @param {Object} msg + */ +function onImplMessage(msg) { + if (!msg || typeof msg !== 'object') { + return; + } + + switch (msg.type) { + case 'signal': { + panxoData = mergeDeep({}, msg.data || {}); + if (!implReady) { + implReady = true; + flushPendingCallbacks(); + } + break; + } + case 'error': { + logError('impl', msg.data || ''); + if (!implReady) { + implReady = true; + flushPendingCallbacks(); + } + break; + } + } +} + +/** + * Flush all pending getBidRequestData callbacks. + * Called when the implementation script sends its first signal. + */ +function flushPendingCallbacks() { + const cbs = pendingCallbacks.splice(0); + cbs.forEach(cb => cb()); +} + +/** + * Called once per auction to enrich bid request ORTB data. + * + * If the implementation script has already sent signal data, enrichment + * happens synchronously and the callback fires immediately. Otherwise the + * callback is deferred until the first signal arrives. The Prebid RTD + * framework enforces `auctionDelay` as the upper bound on this wait, so + * the auction is never blocked indefinitely. + * + * Adds the following fields: + * - device.ext.panxo: session signal token for traffic verification + * - site.ext.data.panxo: contextual AI traffic classification data + * + * @param {Object} reqBidsConfigObj + * @param {function} callback + * @param {SubmoduleConfig} config + * @param {UserConsentData} userConsent + */ +function onGetBidRequestData(reqBidsConfigObj, callback, config, userConsent) { + function enrichAndDone() { + const ortb2 = {}; + + // Add device-level signal (opaque session token) + if (panxoData.device) { + mergeDeep(ortb2, { device: { ext: { panxo: panxoData.device } } }); + } + + // Add site-level contextual data (AI classification) + if (panxoData.site && Object.keys(panxoData.site).length > 0) { + mergeDeep(ortb2, { site: { ext: { data: { panxo: panxoData.site } } } }); + } + + mergeDeep(reqBidsConfigObj.ortb2Fragments.global, ortb2); + callback(); + } + + // If data already arrived, proceed immediately + if (implReady) { + enrichAndDone(); + return; + } + + // Otherwise, wait for the implementation script to send its first signal. + // The auctionDelay configured by the publisher (e.g. 1500ms) acts as the + // maximum wait time -- Prebid will call our callback when it expires. + pendingCallbacks.push(enrichAndDone); +} + +/** + * Exporting local functions for testing purposes. + */ +export const __TEST__ = { + SUBMODULE_NAME, + SCRIPT_URL, + main, + load, + onImplLoaded, + onImplMessage, + onGetBidRequestData, + flushPendingCallbacks +}; + +main(); diff --git a/modules/panxoRtdProvider.md b/modules/panxoRtdProvider.md new file mode 100644 index 00000000000..bc9be90d152 --- /dev/null +++ b/modules/panxoRtdProvider.md @@ -0,0 +1,45 @@ +# Overview + +``` +Module Name: Panxo RTD Provider +Module Type: RTD Provider +Maintainer: prebid@panxo.ai +``` + +# Description + +The Panxo RTD module enriches OpenRTB bid requests with real-time AI traffic classification signals. It detects visits originating from AI assistants and provides contextual data through `device.ext.panxo` and `site.ext.data.panxo`, enabling the Panxo Bid Adapter and other demand partners to apply differentiated bidding on AI-referred inventory. + +To use this module, contact [publishers@panxo.ai](mailto:publishers@panxo.ai) or sign up at [app.panxo.com](https://app.panxo.com) to receive your property identifier. + +# Build + +```bash +gulp build --modules=rtdModule,panxoRtdProvider,... +``` + +> `rtdModule` is required to use the Panxo RTD module. + +# Configuration + +```javascript +pbjs.setConfig({ + realTimeData: { + auctionDelay: 300, + dataProviders: [{ + name: 'panxo', + waitForIt: true, + params: { + siteId: 'a1b2c3d4e5f67890' + } + }] + } +}); +``` + +## Parameters + +| Name | Type | Description | Required | +| :-------- | :------ | :----------------------------------------------------- | :------- | +| `siteId` | String | 16-character hex property identifier provided by Panxo | Yes | +| `verbose` | Boolean | Enable verbose logging for troubleshooting | No | diff --git a/modules/performaxBidAdapter.js b/modules/performaxBidAdapter.js index 48dd4366f1d..8a7b8569594 100644 --- a/modules/performaxBidAdapter.js +++ b/modules/performaxBidAdapter.js @@ -39,11 +39,11 @@ export const spec = { }, buildRequests: function (bidRequests, bidderRequest) { - const data = converter.toORTB({bidderRequest, bidRequests}) + const data = converter.toORTB({ bidderRequest, bidRequests }) return [{ method: 'POST', url: ENDPOINT, - options: {'contentType': 'application/json'}, + options: { 'contentType': 'application/json' }, data: data }] }, diff --git a/modules/permutiveIdentityManagerIdSystem.js b/modules/permutiveIdentityManagerIdSystem.js index cbd2a1b0d2b..4f6404d842a 100644 --- a/modules/permutiveIdentityManagerIdSystem.js +++ b/modules/permutiveIdentityManagerIdSystem.js @@ -1,9 +1,9 @@ -import {MODULE_TYPE_UID} from '../src/activities/modules.js' -import {submodule} from '../src/hook.js' -import {getStorageManager} from '../src/storageManager.js' -import {deepAccess, prefixLog, safeJSONParse} from '../src/utils.js' -import {hasPurposeConsent} from '../libraries/permutiveUtils/index.js' -import {VENDORLESS_GVLID} from "../src/consentHandler.js"; +import { MODULE_TYPE_UID } from '../src/activities/modules.js' +import { submodule } from '../src/hook.js' +import { getStorageManager } from '../src/storageManager.js' +import { deepAccess, prefixLog, safeJSONParse } from '../src/utils.js' +import { hasPurposeConsent } from '../libraries/permutiveUtils/index.js' +import { VENDORLESS_GVLID } from "../src/consentHandler.js"; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule * @typedef {import('../modules/userId/index.js').SubmoduleConfig} SubmoduleConfig @@ -21,7 +21,7 @@ const GOOGLE_DOMAIN = 'google.com' const PRIMARY_IDS = ['id5id', 'idl_env', 'uid2', 'pairId'] -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}) +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }) const logger = prefixLog('[PermutiveID]') @@ -107,7 +107,7 @@ export const permutiveIdentityManagerIdSubmodule = { } catch (e) { logger.logInfo('Error parsing pairId') } - return pairId === undefined ? value : {...value, pairId} + return pairId === undefined ? value : { ...value, pairId } }, /** diff --git a/modules/permutiveRtdProvider.js b/modules/permutiveRtdProvider.js index 972154e3933..09697b6f906 100644 --- a/modules/permutiveRtdProvider.js +++ b/modules/permutiveRtdProvider.js @@ -5,14 +5,14 @@ * @module modules/permutiveRtdProvider * @requires module:modules/realTimeData */ -import {getGlobal} from '../src/prebidGlobal.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {deepAccess, deepSetValue, isFn, logError, mergeDeep, isPlainObject, safeJSONParse, prefixLog} from '../src/utils.js'; -import {VENDORLESS_GVLID} from '../src/consentHandler.js'; -import {hasPurposeConsent} from '../libraries/permutiveUtils/index.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { deepAccess, deepSetValue, isFn, logError, mergeDeep, isPlainObject, safeJSONParse, prefixLog } from '../src/utils.js'; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; +import { hasPurposeConsent } from '../libraries/permutiveUtils/index.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -27,7 +27,7 @@ export const PERMUTIVE_STANDARD_KEYWORD = 'p_standard' export const PERMUTIVE_CUSTOM_COHORTS_KEYWORD = 'permutive' export const PERMUTIVE_STANDARD_AUD_KEYWORD = 'p_standard_aud' -export const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME}) +export const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: MODULE_NAME }) function init(moduleConfig, userConsent) { readPermutiveModuleConfigFromCache() diff --git a/modules/prebidServerBidAdapter/bidderConfig.js b/modules/prebidServerBidAdapter/bidderConfig.js index b009bb9bcfa..f860f0337b4 100644 --- a/modules/prebidServerBidAdapter/bidderConfig.js +++ b/modules/prebidServerBidAdapter/bidderConfig.js @@ -1,5 +1,5 @@ -import {mergeDeep, deepEqual, deepAccess, deepSetValue, deepClone} from '../../src/utils.js'; -import {ORTB_EIDS_PATHS} from '../../src/activities/redactor.js'; +import { mergeDeep, deepEqual, deepAccess, deepSetValue, deepClone } from '../../src/utils.js'; +import { ORTB_EIDS_PATHS } from '../../src/activities/redactor.js'; /** * Perform a partial pre-merge of bidder config for PBS. @@ -11,7 +11,7 @@ import {ORTB_EIDS_PATHS} from '../../src/activities/redactor.js'; * This returns bidder config (from `bidder`) where arrays are replaced with what you get from merging them with `global`, * so that the result of merging in PBS is the same as in JS. */ -export function getPBSBidderConfig({global, bidder}) { +export function getPBSBidderConfig({ global, bidder }) { return Object.fromEntries( Object.entries(bidder).map(([bidderCode, bidderConfig]) => { return [bidderCode, replaceArrays(bidderConfig, mergeDeep({}, global, bidderConfig))] @@ -44,7 +44,7 @@ function replaceArrays(config, mergedConfig) { * `bidders` is a list of all the bidders that refer to that specific EID object, or false if that EID object is defined globally. * - `conflicts` is a set containing all EID sources that appear in multiple, otherwise different, EID objects. */ -export function extractEids({global, bidder}) { +export function extractEids({ global, bidder }) { const entries = []; const bySource = {}; const conflicts = new Set() @@ -52,7 +52,7 @@ export function extractEids({global, bidder}) { function getEntry(eid) { let entry = entries.find((candidate) => deepEqual(candidate.eid, eid)); if (entry == null) { - entry = {eid, bidders: new Set()} + entry = { eid, bidders: new Set() } entries.push(entry); } if (bySource[eid.source] == null) { @@ -79,7 +79,7 @@ export function extractEids({global, bidder}) { }) }) }) - return {eids: entries.map(({eid, bidders}) => ({eid, bidders: bidders && Array.from(bidders)})), conflicts}; + return { eids: entries.map(({ eid, bidders }) => ({ eid, bidders: bidders && Array.from(bidders) })), conflicts }; } /** @@ -95,16 +95,16 @@ export function extractEids({global, bidder}) { * - `bidder` is a map from bidder code to EID objects that are specific to that bidder, and cannot be restricted through `permissions` * - `permissions` is a list of EID permissions as expected by PBS. */ -export function consolidateEids({eids, conflicts = new Set()}) { +export function consolidateEids({ eids, conflicts = new Set() }) { const globalEntries = []; const bidderEntries = []; const byBidder = {}; eids.forEach(eid => { (eid.bidders === false ? globalEntries : bidderEntries).push(eid); }); - bidderEntries.forEach(({eid, bidders}) => { + bidderEntries.forEach(({ eid, bidders }) => { if (!conflicts.has(eid.source)) { - globalEntries.push({eid, bidders}) + globalEntries.push({ eid, bidders }) } else { bidders.forEach(bidderCode => { (byBidder[bidderCode] = byBidder[bidderCode] || []).push(eid) @@ -112,8 +112,8 @@ export function consolidateEids({eids, conflicts = new Set()}) { } }); return { - global: globalEntries.map(({eid}) => eid), - permissions: globalEntries.filter(({bidders}) => bidders !== false).map(({eid, bidders}) => ({ + global: globalEntries.map(({ eid }) => eid), + permissions: globalEntries.filter(({ bidders }) => bidders !== false).map(({ eid, bidders }) => ({ source: eid.source, bidders })), @@ -121,8 +121,8 @@ export function consolidateEids({eids, conflicts = new Set()}) { } } -function replaceEids({global, bidder}, requestedBidders) { - const consolidated = consolidateEids(extractEids({global, bidder})); +function replaceEids({ global, bidder }, requestedBidders) { + const consolidated = consolidateEids(extractEids({ global, bidder })); global = deepClone(global); bidder = deepClone(bidder); function removeEids(target) { @@ -147,7 +147,7 @@ function replaceEids({global, bidder}, requestedBidders) { deepSetValue(bidder[bidderCode], 'user.ext.eids', bidderEids); } }) - return {global, bidder} + return { global, bidder } } export function premergeFpd(ortb2Fragments, requestedBidders) { diff --git a/modules/prebidServerBidAdapter/index.ts b/modules/prebidServerBidAdapter/index.ts index 71abec10cee..9f875321934 100644 --- a/modules/prebidServerBidAdapter/index.ts +++ b/modules/prebidServerBidAdapter/index.ts @@ -18,23 +18,23 @@ import { triggerPixel, uniques, } from '../../src/utils.js'; -import {DEBUG_MODE, EVENTS, REJECTION_REASON, S2S} from '../../src/constants.js'; -import adapterManager, {s2sActivityParams} from '../../src/adapterManager.js'; -import {config} from '../../src/config.js'; -import {addPaapiConfig, isValid} from '../../src/adapters/bidderFactory.js'; +import { DEBUG_MODE, EVENTS, REJECTION_REASON, S2S } from '../../src/constants.js'; +import adapterManager, { s2sActivityParams } from '../../src/adapterManager.js'; +import { config } from '../../src/config.js'; +import { addPaapiConfig, isValid } from '../../src/adapters/bidderFactory.js'; import * as events from '../../src/events.js'; -import {ajax} from '../../src/ajax.js'; -import {hook} from '../../src/hook.js'; -import {hasPurpose1Consent} from '../../src/utils/gdpr.js'; -import {buildPBSRequest, interpretPBSResponse} from './ortbConverter.js'; -import {useMetrics} from '../../src/utils/perfMetrics.js'; -import {isActivityAllowed} from '../../src/activities/rules.js'; -import {ACTIVITY_TRANSMIT_UFPD} from '../../src/activities/activities.js'; -import type {Identifier, BidderCode} from '../../src/types/common.d.ts'; -import type {Metrics} from "../../src/utils/perfMetrics.ts"; -import type {ORTBResponse} from "../../src/types/ortb/response.d.ts"; -import type {NativeRequest} from '../../src/types/ortb/native.d.ts'; -import type {SyncType} from "../../src/userSync.ts"; +import { ajax } from '../../src/ajax.js'; +import { hook } from '../../src/hook.js'; +import { hasPurpose1Consent } from '../../src/utils/gdpr.js'; +import { buildPBSRequest, interpretPBSResponse } from './ortbConverter.js'; +import { useMetrics } from '../../src/utils/perfMetrics.js'; +import { isActivityAllowed } from '../../src/activities/rules.js'; +import { ACTIVITY_TRANSMIT_UFPD } from '../../src/activities/activities.js'; +import type { Identifier, BidderCode } from '../../src/types/common.d.ts'; +import type { Metrics } from "../../src/utils/perfMetrics.ts"; +import type { ORTBResponse } from "../../src/types/ortb/response.d.ts"; +import type { NativeRequest } from '../../src/types/ortb/native.d.ts'; +import type { SyncType } from "../../src/userSync.ts"; const getConfig = config.getConfig; @@ -155,7 +155,7 @@ export const s2sDefaultConfig: Partial = { syncUrlModifier: {}, ortbNative: { eventtrackers: [ - {event: 1, methods: [1, 2]} + { event: 1, methods: [1, 2] } ], }, maxTimeout: 1500, @@ -247,7 +247,7 @@ function setS2sConfig(options) { _s2sConfigs = options; } } -getConfig('s2sConfig', ({s2sConfig}) => setS2sConfig(s2sConfig)); +getConfig('s2sConfig', ({ s2sConfig }) => setS2sConfig(s2sConfig)); /** * resets the _synced variable back to false, primiarily used for testing purposes @@ -477,7 +477,7 @@ export function PrebidServer() { .newMetrics() .renameWith((n) => [`adapter.s2s.${n}`, `adapters.s2s.${s2sBidRequest.s2sConfig.defaultVendor}.${n}`]) done = adapterMetrics.startTiming('total').stopBefore(done); - bidRequests.forEach(req => useMetrics(req.metrics).join(adapterMetrics, {stopPropagation: true})); + bidRequests.forEach(req => useMetrics(req.metrics).join(adapterMetrics, { stopPropagation: true })); const { gdprConsent, uspConsent, gppConsent } = getConsentData(bidRequests); @@ -522,7 +522,7 @@ export function PrebidServer() { doClientSideSyncs(requestedBidders, gdprConsent, uspConsent, gppConsent); }, onError(msg, error) { - const {p1Consent = '', noP1Consent = ''} = s2sBidRequest?.s2sConfig?.endpoint || {}; + const { p1Consent = '', noP1Consent = '' } = s2sBidRequest?.s2sConfig?.endpoint || {}; if (p1Consent === noP1Consent) { logError(`Prebid server call failed: '${msg}'. Endpoint: "${p1Consent}"}`, error); } else { @@ -531,7 +531,7 @@ export function PrebidServer() { bidRequests.forEach(bidderRequest => events.emit(EVENTS.BIDDER_ERROR, { error, bidderRequest })); done(error.timedOut); }, - onBid: function ({adUnit, bid}) { + onBid: function ({ adUnit, bid }) { const metrics = bid.metrics = s2sBidRequest.metrics.fork().renameWith(); metrics.checkpoint('addBidResponse'); if ((bid.requestId == null || bid.requestBidder == null) && !s2sBidRequest.s2sConfig.allowUnknownBidderCodes) { @@ -547,7 +547,7 @@ export function PrebidServer() { }, onFledge: (params) => { config.runWithBidder(params.bidder, () => { - addPaapiConfig({auctionId: bidRequests[0].auctionId, ...params}, {config: params.config}); + addPaapiConfig({ auctionId: bidRequests[0].auctionId, ...params }, { config: params.config }); }) } }) @@ -577,7 +577,7 @@ type PbsRequestData = { * @param onError {function(String, {})} invoked on HTTP failure - with status message and XHR error * @param onBid {function({})} invoked once for each bid in the response - with the bid as returned by interpretResponse */ -export const processPBSRequest = hook('async', function (s2sBidRequest, bidRequests, ajax, {onResponse, onError, onBid, onFledge}) { +export const processPBSRequest = hook('async', function (s2sBidRequest, bidRequests, ajax, { onResponse, onError, onBid, onFledge }) { const { gdprConsent } = getConsentData(bidRequests); const adUnits = deepClone(s2sBidRequest.ad_units); @@ -606,7 +606,7 @@ export const processPBSRequest = hook('async', function (s2sBidRequest, bidReque let result; try { result = JSON.parse(response); - const {bids, paapi} = s2sBidRequest.metrics.measureTime('interpretResponse', () => interpretPBSResponse(result, request)); + const { bids, paapi } = s2sBidRequest.metrics.measureTime('interpretResponse', () => interpretPBSResponse(result, request)); bids.forEach(onBid); if (paapi) { paapi.forEach(onFledge); diff --git a/modules/prebidServerBidAdapter/ortbConverter.js b/modules/prebidServerBidAdapter/ortbConverter.js index ab9e18e6837..0ced549fca6 100644 --- a/modules/prebidServerBidAdapter/ortbConverter.js +++ b/modules/prebidServerBidAdapter/ortbConverter.js @@ -1,23 +1,23 @@ -import {ortbConverter} from '../../libraries/ortbConverter/converter.js'; -import {deepClone, deepSetValue, getBidRequest, logError, logWarn, mergeDeep, timestamp} from '../../src/utils.js'; -import {config} from '../../src/config.js'; -import {S2S} from '../../src/constants.js'; -import {createBid} from '../../src/bidfactory.js'; -import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js'; -import {setImpBidParams} from '../../libraries/pbsExtensions/processors/params.js'; -import {SUPPORTED_MEDIA_TYPES} from '../../libraries/pbsExtensions/processors/mediaType.js'; -import {IMP, REQUEST, RESPONSE} from '../../src/pbjsORTB.js'; -import {redactor} from '../../src/activities/redactor.js'; -import {s2sActivityParams} from '../../src/adapterManager.js'; -import {activityParams} from '../../src/activities/activityParams.js'; -import {MODULE_TYPE_BIDDER} from '../../src/activities/modules.js'; -import {isActivityAllowed} from '../../src/activities/rules.js'; -import {ACTIVITY_TRANSMIT_TID} from '../../src/activities/activities.js'; -import {currencyCompare} from '../../libraries/currencyUtils/currency.js'; -import {minimum} from '../../src/utils/reducers.js'; -import {s2sDefaultConfig} from './index.js'; -import {premergeFpd} from './bidderConfig.js'; -import {ALL_MEDIATYPES, BANNER} from '../../src/mediaTypes.js'; +import { ortbConverter } from '../../libraries/ortbConverter/converter.js'; +import { deepClone, deepSetValue, getBidRequest, logError, logWarn, mergeDeep, timestamp } from '../../src/utils.js'; +import { config } from '../../src/config.js'; +import { S2S } from '../../src/constants.js'; +import { createBid } from '../../src/bidfactory.js'; +import { pbsExtensions } from '../../libraries/pbsExtensions/pbsExtensions.js'; +import { setImpBidParams } from '../../libraries/pbsExtensions/processors/params.js'; +import { SUPPORTED_MEDIA_TYPES } from '../../libraries/pbsExtensions/processors/mediaType.js'; +import { IMP, REQUEST, RESPONSE } from '../../src/pbjsORTB.js'; +import { redactor } from '../../src/activities/redactor.js'; +import { s2sActivityParams } from '../../src/adapterManager.js'; +import { activityParams } from '../../src/activities/activityParams.js'; +import { MODULE_TYPE_BIDDER } from '../../src/activities/modules.js'; +import { isActivityAllowed } from '../../src/activities/rules.js'; +import { ACTIVITY_TRANSMIT_TID } from '../../src/activities/activities.js'; +import { currencyCompare } from '../../libraries/currencyUtils/currency.js'; +import { minimum } from '../../src/utils/reducers.js'; +import { s2sDefaultConfig } from './index.js'; +import { premergeFpd } from './bidderConfig.js'; +import { ALL_MEDIATYPES, BANNER } from '../../src/mediaTypes.js'; const DEFAULT_S2S_TTL = 60; const DEFAULT_S2S_CURRENCY = 'USD'; @@ -59,7 +59,7 @@ const PBS_CONVERTER = ortbConverter({ if (!imps.length) { logError('Request to Prebid Server rejected due to invalid media type(s) in adUnit.'); } else { - const {s2sBidRequest} = context; + const { s2sBidRequest } = context; const request = buildRequest(imps, proxyBidderRequest, context); request.tmax = Math.floor(s2sBidRequest.s2sConfig.timeout ?? Math.min(s2sBidRequest.requestBidsTimeout * 0.75, s2sBidRequest.s2sConfig.maxTimeout ?? s2sDefaultConfig.maxTimeout)); @@ -200,7 +200,7 @@ const PBS_CONVERTER = ortbConverter({ }).map(([bidder, ortb2]) => ({ // ... but for bidder specific FPD we can use the actual bidder bidders: [bidder], - config: {ortb2: context.getRedactor(bidder).ortb2(ortb2)} + config: { ortb2: context.getRedactor(bidder).ortb2(ortb2) } })); if (fpdConfigs.length) { deepSetValue(ortbRequest, 'ext.prebid.bidderconfig', fpdConfigs); @@ -219,16 +219,16 @@ const PBS_CONVERTER = ortbConverter({ bidders: [req.bidderCode], schain: req?.bids?.[0]?.ortb2?.source?.ext?.schain }))) - .filter(({bidders, schain}) => bidders?.length > 0 && schain) - .reduce((chains, {bidders, schain}) => { + .filter(({ bidders, schain }) => bidders?.length > 0 && schain) + .reduce((chains, { bidders, schain }) => { const key = JSON.stringify(schain); if (!chains.hasOwnProperty(key)) { - chains[key] = {bidders: new Set(), schain}; + chains[key] = { bidders: new Set(), schain }; } bidders.forEach((bidder) => chains[key].bidders.add(bidder)); return chains; }, {}) - ).map(({bidders, schain}) => ({bidders: Array.from(bidders), schain})); + ).map(({ bidders, schain }) => ({ bidders: Array.from(bidders), schain })); if (chains.length) { deepSetValue(ortbRequest, 'ext.prebid.schains', chains); @@ -246,7 +246,7 @@ const PBS_CONVERTER = ortbConverter({ [RESPONSE]: { serverSideStats(orig, response, ortbResponse, context) { // override to process each request - context.actualBidderRequests.forEach(req => orig(response, ortbResponse, {...context, bidderRequest: req, bidRequests: req.bids})); + context.actualBidderRequests.forEach(req => orig(response, ortbResponse, { ...context, bidderRequest: req, bidRequests: req.bids })); }, paapiConfigs(orig, response, ortbResponse, context) { const configs = Object.values(context.impContext) @@ -311,7 +311,7 @@ export function buildPBSRequest(s2sBidRequest, bidderRequests, adUnits, requeste proxyBidRequests.push({ ...adUnit, adUnitCode: adUnit.code, - pbsData: {impId, actualBidRequests, adUnit}, + pbsData: { impId, actualBidRequests, adUnit }, }); }); @@ -343,5 +343,5 @@ export function buildPBSRequest(s2sBidRequest, bidderRequests, adUnits, requeste } export function interpretPBSResponse(response, request) { - return PBS_CONVERTER.fromORTB({response, request}); + return PBS_CONVERTER.fromORTB({ response, request }); } diff --git a/modules/previousAuctionInfo/index.js b/modules/previousAuctionInfo/index.js index 3846a46812a..179d25e555e 100644 --- a/modules/previousAuctionInfo/index.js +++ b/modules/previousAuctionInfo/index.js @@ -1,8 +1,8 @@ -import {on as onEvent, off as offEvent} from '../../src/events.js'; +import { on as onEvent, off as offEvent } from '../../src/events.js'; import { EVENTS } from '../../src/constants.js'; import { config } from '../../src/config.js'; -import {deepSetValue} from '../../src/utils.js'; -import {startAuction} from '../../src/prebid.js'; +import { deepSetValue } from '../../src/utils.js'; +import { startAuction } from '../../src/prebid.js'; export const CONFIG_NS = 'previousAuctionInfo'; export let previousAuctionInfoEnabled = false; let enabledBidders = []; @@ -19,7 +19,7 @@ export function resetPreviousAuctionInfo() { } function initPreviousAuctionInfo() { - config.getConfig('previousAuctionInfo', ({[CONFIG_NS]: config = {}}) => { + config.getConfig('previousAuctionInfo', ({ [CONFIG_NS]: config = {} }) => { if (!config?.enabled) { resetPreviousAuctionInfo(); return; @@ -46,7 +46,7 @@ const deinitHandlers = () => { if (handlersAttached) { offEvent(EVENTS.AUCTION_END, onAuctionEndHandler); offEvent(EVENTS.BID_WON, onBidWonHandler); - startAuction.getHooks({hook: startAuctionHook}).remove(); + startAuction.getHooks({ hook: startAuctionHook }).remove(); handlersAttached = false; } } diff --git a/modules/priceFloors.ts b/modules/priceFloors.ts index 45460c66425..2eacebdd575 100644 --- a/modules/priceFloors.ts +++ b/modules/priceFloors.ts @@ -15,25 +15,25 @@ import { deepEqual, generateUUID } from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {config} from '../src/config.js'; -import {ajaxBuilder} from '../src/ajax.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { config } from '../src/config.js'; +import { ajaxBuilder } from '../src/ajax.js'; import * as events from '../src/events.js'; import { EVENTS, REJECTION_REASON } from '../src/constants.js'; -import {getHook} from '../src/hook.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {bidderSettings} from '../src/bidderSettings.js'; -import {auctionManager} from '../src/auctionManager.js'; -import {IMP, PBS, registerOrtbProcessor, REQUEST} from '../src/pbjsORTB.js'; -import {timedAuctionHook, timedBidResponseHook} from '../src/utils/perfMetrics.js'; -import {adjustCpm} from '../src/utils/cpm.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; -import {convertCurrency} from '../libraries/currencyUtils/currency.js'; +import { getHook } from '../src/hook.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { bidderSettings } from '../src/bidderSettings.js'; +import { auctionManager } from '../src/auctionManager.js'; +import { IMP, PBS, registerOrtbProcessor, REQUEST } from '../src/pbjsORTB.js'; +import { timedAuctionHook, timedBidResponseHook } from '../src/utils/perfMetrics.js'; +import { adjustCpm } from '../src/utils/cpm.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; +import { convertCurrency } from '../libraries/currencyUtils/currency.js'; import { timeoutQueue } from '../libraries/timeoutQueue/timeoutQueue.js'; -import {ALL_MEDIATYPES, BANNER, type MediaType} from '../src/mediaTypes.js'; -import type {Currency, Size, BidderCode} from "../src/types/common.d.ts"; -import type {BidRequest} from '../src/adapterManager.ts'; -import type {Bid} from "../src/bidfactory.ts"; +import { ALL_MEDIATYPES, BANNER, type MediaType } from '../src/mediaTypes.js'; +import type { Currency, Size, BidderCode } from "../src/types/common.d.ts"; +import type { BidRequest } from '../src/adapterManager.ts'; +import type { Bid } from "../src/bidfactory.ts"; export const FLOOR_SKIPPED_REASON = { NOT_FOUND: 'not_found', @@ -57,7 +57,7 @@ const SYN_FIELD = Symbol(); * @summary Allowed fields for rules to have */ export const allowedFields = [SYN_FIELD, 'gptSlot', 'adUnitCode', 'size', 'domain', 'mediaType'] as const; -type DefaultField = { [K in (typeof allowedFields)[number]]: K extends string ? K : never}[(typeof allowedFields)[number]]; +type DefaultField = { [K in (typeof allowedFields)[number]]: K extends string ? K : never }[(typeof allowedFields)[number]]; /** * @summary Global set to track valid userId tier fields @@ -115,7 +115,7 @@ const getHostname = (() => { let domain; return function() { if (domain == null) { - domain = parseUrl(getRefererInfo().topmostLocation, {noDecodeWholeURL: true}).hostname; + domain = parseUrl(getRefererInfo().topmostLocation, { noDecodeWholeURL: true }).hostname; } return domain; } @@ -148,13 +148,13 @@ export function resolveTierUserIds(tiers, bidRequest) { }, {}); } -function getGptSlotFromAdUnit(adUnitId, {index = auctionManager.index} = {}) { - const adUnit = index.getAdUnit({adUnitId}); +function getGptSlotFromAdUnit(adUnitId, { index = auctionManager.index } = {}) { + const adUnit = index.getAdUnit({ adUnitId }); const isGam = deepAccess(adUnit, 'ortb2Imp.ext.data.adserver.name') === 'gam'; return isGam && adUnit.ortb2Imp.ext.data.adserver.adslot; } -function getAdUnitCode(request, response, {index = auctionManager.index} = {}) { +function getAdUnitCode(request, response, { index = auctionManager.index } = {}) { return request?.adUnitCode || index.getAdUnit(response).code; } @@ -209,7 +209,7 @@ function enumeratePossibleFieldValues(floorFields, bidObject, responseObject) { export function getFirstMatchingFloor(floorData, bidObject, responseObject = {}) { const fieldValues = enumeratePossibleFieldValues(deepAccess(floorData, 'schema.fields') || [], bidObject, responseObject); if (!fieldValues.length) { - return {matchingFloor: undefined} + return { matchingFloor: undefined } } // look to see if a request for this context was made already @@ -217,7 +217,7 @@ export function getFirstMatchingFloor(floorData, bidObject, responseObject = {}) // if we already have gotten the matching rule from this matching input then use it! No need to look again const previousMatch = deepAccess(floorData, `matchingInputs.${matchingInput}`); if (previousMatch) { - return {...previousMatch}; + return { ...previousMatch }; } const allPossibleMatches = generatePossibleEnumerations(fieldValues, deepAccess(floorData, 'schema.delimiter') || '|'); const matchingRule = ((allPossibleMatches) || []).find(hashValue => floorData.values.hasOwnProperty(hashValue)); @@ -235,7 +235,7 @@ export function getFirstMatchingFloor(floorData, bidObject, responseObject = {}) } matchingData.matchingFloor = Math.max(matchingData.floorMin, matchingData.floorRuleValue); // save for later lookup if needed - deepSetValue(floorData, `matchingInputs.${matchingInput}`, {...matchingData}); + deepSetValue(floorData, `matchingInputs.${matchingInput}`, { ...matchingData }); return matchingData; } @@ -260,7 +260,7 @@ function generatePossibleEnumerations(arrayOfFields, delimiter) { * @summary If a the input bidder has a registered cpmadjustment it returns the input CPM after being adjusted */ export function getBiddersCpmAdjustment(inputCpm, bid, bidRequest) { - return parseFloat(adjustCpm(inputCpm, {...bid, cpm: inputCpm}, bidRequest)); + return parseFloat(adjustCpm(inputCpm, { ...bid, cpm: inputCpm }, bidRequest)); } /** @@ -316,7 +316,7 @@ declare module '../src/bidderSettings' { /** * Inverse of bidCpmAdjustment */ - inverseBidAdjustment?: (floor: number, bidRequest: BidRequest, params: {[K in keyof GetFloorParams]?: Exclude}) => number; + inverseBidAdjustment?: (floor: number, bidRequest: BidRequest, params: { [K in keyof GetFloorParams]?: Exclude }) => number; } } @@ -324,14 +324,14 @@ declare module '../src/bidderSettings' { * @summary This is the function which will return a single floor based on the input requests * and matching it to a rule for the current auction */ -export function getFloor(requestParams: GetFloorParams = {currency: 'USD', mediaType: '*', size: '*'}) { +export function getFloor(requestParams: GetFloorParams = { currency: 'USD', mediaType: '*', size: '*' }) { // eslint-disable-next-line @typescript-eslint/no-this-alias const bidRequest = this; const floorData = _floorDataForAuction[bidRequest.auctionId]; if (!floorData || floorData.skipped) return {}; requestParams = updateRequestParamsFromContext(bidRequest, requestParams); - const floorInfo = getFirstMatchingFloor(floorData.data, {...bidRequest}, {mediaType: requestParams.mediaType, size: requestParams.size}); + const floorInfo = getFirstMatchingFloor(floorData.data, { ...bidRequest }, { mediaType: requestParams.mediaType, size: requestParams.size }); let currency = requestParams.currency || floorData.data.currency; // if bidder asked for a currency which is not what floors are set in convert @@ -367,7 +367,8 @@ export function getFloor(requestParams: GetFloorParams = {currency: 'USD', media if (floorInfo.matchingFloor) { return { floor: roundUp(floorInfo.matchingFloor, 4), - currency}; + currency + }; } return {}; } @@ -412,7 +413,7 @@ export function getFloorDataFromAdUnits(adUnits) { logError(`${MODULE_NAME}: adUnit '${adUnit.code}' declares a different schema from one previously declared by adUnit '${schemaAu.code}'. Floor config for '${adUnit.code}' will be ignored.`) return accum; } - const floors = Object.assign({}, schemaAu?.floors, {values: undefined}, adUnit.floors) + const floors = Object.assign({}, schemaAu?.floors, { values: undefined }, adUnit.floors) if (isFloorsDataValid(floors)) { // if values already exist we want to not overwrite them if (!accum.values) { @@ -585,7 +586,7 @@ export function normalizeDefault(model) { model.values = model.values || {}; if (model.values[defaultRule] == null) { model.values[defaultRule] = model.default; - model.meta = {defaultRule}; + model.meta = { defaultRule }; } } return model; @@ -843,6 +844,11 @@ export type FloorsConfig = Pick * If set to false, the Price Floors Module will still provide floors for bid adapters, there will be no floor enforcement. */ enforceJS?: boolean; + /** + * Array of bidders to enforce JS floors on when enforceJS is true. + * Defaults to ['*'] (all bidders). + */ + enforceBidders?: (BidderCode | '*')[]; /** * If set to true (the default), the Price Floors Module will signal to Prebid Server to pass floors to it’s bid * adapters and enforce floors. @@ -901,6 +907,7 @@ export function handleSetFloorsConfig(config) { 'userIds', validateUserIdsConfig, 'enforcement', enforcement => pick(enforcement || {}, [ 'enforceJS', enforceJS => enforceJS !== false, // defaults to true + 'enforceBidders', enforceBidders => Array.isArray(enforceBidders) && enforceBidders.length > 0 ? enforceBidders : ['*'], 'enforcePBS', enforcePBS => enforcePBS === true, // defaults to false 'floorDeals', floorDeals => floorDeals === true, // defaults to false 'bidAdjustment', bidAdjustment => bidAdjustment !== false, // defaults to true, @@ -935,8 +942,8 @@ export function handleSetFloorsConfig(config) { _floorsConfig = {}; _floorDataForAuction = {}; - getHook('addBidResponse').getHooks({hook: addBidResponseHook}).remove(); - getHook('requestBids').getHooks({hook: requestBidsHook}).remove(); + getHook('addBidResponse').getHooks({ hook: addBidResponseHook }).remove(); + getHook('requestBids').getHooks({ hook: requestBidsHook }).remove(); addedFloorsHook = false; } @@ -969,7 +976,7 @@ function addFloorDataToBid(floorData, floorInfo, bid: Partial, adjustedCpm) floorRuleValue: floorInfo.floorRuleValue, floorCurrency: floorData.data.currency, cpmAfterAdjustments: adjustedCpm, - enforcements: {...floorData.enforcement}, + enforcements: { ...floorData.enforcement }, matchedFields: {} }; floorData.data.schema.fields.forEach((field, index) => { @@ -983,9 +990,12 @@ function addFloorDataToBid(floorData, floorInfo, bid: Partial, adjustedCpm) */ function shouldFloorBid(floorData, floorInfo, bid) { const enforceJS = deepAccess(floorData, 'enforcement.enforceJS') !== false; + const enforceBidders = deepAccess(floorData, 'enforcement.enforceBidders') || ['*']; + const bidderCode = bid?.adapterCode || bid?.bidderCode || bid?.bidder; + const shouldEnforceBidder = enforceBidders.includes('*') || (bidderCode != null && enforceBidders.includes(bidderCode)); const shouldFloorDeal = deepAccess(floorData, 'enforcement.floorDeals') === true || !bid.dealId; const bidBelowFloor = bid.floorData.cpmAfterAdjustments < floorInfo.matchingFloor; - return enforceJS && (bidBelowFloor && shouldFloorDeal); + return enforceJS && shouldEnforceBidder && (bidBelowFloor && shouldFloorDeal); } /** @@ -1002,7 +1012,7 @@ export const addBidResponseHook = timedBidResponseHook('priceFloors', function a const matchingBidRequest = auctionManager.index.getBidRequest(bid); // get the matching rule - const floorInfo = getFirstMatchingFloor(floorData.data, matchingBidRequest, {...bid, size: [bid.width, bid.height]}); + const floorInfo = getFirstMatchingFloor(floorData.data, matchingBidRequest, { ...bid, size: [bid.width, bid.height] }); if (!floorInfo.matchingFloor) { if (floorInfo.matchingFloor !== 0) logWarn(`${MODULE_NAME}: unable to determine a matching price floor for bidResponse`, bid); @@ -1044,7 +1054,7 @@ export const addBidResponseHook = timedBidResponseHook('priceFloors', function a config.getConfig('floors', config => handleSetFloorsConfig(config.floors)); -function tryGetFloor(bidRequest, {currency = config.getConfig('currency.adServerCurrency') || 'USD', mediaType = '*', size = '*'}: GetFloorParams, fn) { +function tryGetFloor(bidRequest, { currency = config.getConfig('currency.adServerCurrency') || 'USD', mediaType = '*', size = '*' }: GetFloorParams, fn) { if (typeof bidRequest.getFloor === 'function') { let floor; try { @@ -1100,7 +1110,7 @@ export function setGranularBidfloors(imp, bidRequest, context) { }, setIfDifferent.bind(imp[mediaType])) }); (imp[BANNER]?.format || []) - .filter(({w, h}) => w != null && h != null) + .filter(({ w, h }) => w != null && h != null) .forEach(format => { tryGetFloor(bidRequest, { currency: imp.bidfloorcur || context?.currency, @@ -1119,7 +1129,7 @@ export function setImpExtPrebidFloors(imp, bidRequest, context) { // 4. set req wide floorMin and floorMinCur values for pbs after iterations are done if (imp.bidfloor != null) { - let {floorMinCur, floorMin} = context.reqContext.floorMin || {}; + let { floorMinCur, floorMin } = context.reqContext.floorMin || {}; if (floorMinCur == null) { floorMinCur = imp.bidfloorcur } const ortb2ImpFloorCur = imp.ext?.prebid?.floors?.floorMinCur || imp.ext?.prebid?.floorMinCur || floorMinCur; @@ -1133,7 +1143,7 @@ export function setImpExtPrebidFloors(imp, bidRequest, context) { deepSetValue(imp, 'ext.prebid.floors.floorMin', lowestImpFloorMin); if (floorMin == null || floorMin > lowestImpFloorMin) { floorMin = lowestImpFloorMin } - context.reqContext.floorMin = {floorMin, floorMinCur}; + context.reqContext.floorMin = { floorMin, floorMinCur }; } } @@ -1145,15 +1155,15 @@ export function setOrtbExtPrebidFloors(ortbRequest, bidderRequest, context) { deepSetValue(ortbRequest, 'ext.prebid.floors.enabled', ortbRequest.ext?.prebid?.floors?.enabled || false); } if (context?.floorMin) { - mergeDeep(ortbRequest, {ext: {prebid: {floors: context.floorMin}}}) + mergeDeep(ortbRequest, { ext: { prebid: { floors: context.floorMin } } }) } } -registerOrtbProcessor({type: IMP, name: 'bidfloor', fn: setOrtbImpBidFloor}); +registerOrtbProcessor({ type: IMP, name: 'bidfloor', fn: setOrtbImpBidFloor }); // granular floors should be set after both "normal" bidfloors and mediaypes -registerOrtbProcessor({type: IMP, name: 'extBidfloor', fn: setGranularBidfloors, priority: -10}) -registerOrtbProcessor({type: IMP, name: 'extPrebidFloors', fn: setImpExtPrebidFloors, dialects: [PBS], priority: -1}); -registerOrtbProcessor({type: REQUEST, name: 'extPrebidFloors', fn: setOrtbExtPrebidFloors, dialects: [PBS]}); +registerOrtbProcessor({ type: IMP, name: 'extBidfloor', fn: setGranularBidfloors, priority: -10 }) +registerOrtbProcessor({ type: IMP, name: 'extPrebidFloors', fn: setImpExtPrebidFloors, dialects: [PBS], priority: -1 }); +registerOrtbProcessor({ type: REQUEST, name: 'extPrebidFloors', fn: setOrtbExtPrebidFloors, dialects: [PBS] }); /** * Validate userIds config: must be an object with array values diff --git a/modules/prismaBidAdapter.js b/modules/prismaBidAdapter.js index 8506d29f82b..b2b7682f878 100644 --- a/modules/prismaBidAdapter.js +++ b/modules/prismaBidAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; -import {getConnectionType} from '../libraries/connectionInfo/connectionUtils.js' +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; +import { getConnectionType } from '../libraries/connectionInfo/connectionUtils.js' /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -177,7 +177,7 @@ export const spec = { }; params.price = bid.cpm; const url = `${METRICS_TRACKER_URL}?${new URLSearchParams(params).toString()}`; - ajax(url, null, undefined, {method: 'GET', withCredentials: true}); + ajax(url, null, undefined, { method: 'GET', withCredentials: true }); return true; } diff --git a/modules/programmaticXBidAdapter.js b/modules/programmaticXBidAdapter.js index 1f0333b9a3c..413210beafa 100644 --- a/modules/programmaticXBidAdapter.js +++ b/modules/programmaticXBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { createBuildRequestsFn, createInterpretResponseFn, @@ -13,7 +13,7 @@ const BIDDER_CODE = 'programmaticX'; const BIDDER_VERSION = '1.0.0'; const GVLID = 1344; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.programmaticx.ai`; diff --git a/modules/programmaticaBidAdapter.js b/modules/programmaticaBidAdapter.js index 7ae2ae8404a..525f495f525 100644 --- a/modules/programmaticaBidAdapter.js +++ b/modules/programmaticaBidAdapter.js @@ -13,8 +13,8 @@ export const spec = { isBidRequestValid: sspValidRequest, buildRequests: sspBuildRequests(DEFAULT_ENDPOINT), interpretResponse: sspInterpretResponse(TIME_TO_LIVE, ADOMAIN), - getUserSyncs: getUserSyncs(SYNC_ENDPOINT, {usp: 'usp', consent: 'consent'}), - supportedMediaTypes: [ BANNER, VIDEO ] + getUserSyncs: getUserSyncs(SYNC_ENDPOINT, { usp: 'usp', consent: 'consent' }), + supportedMediaTypes: [BANNER, VIDEO] } registerBidder(spec); diff --git a/modules/proxistoreBidAdapter.js b/modules/proxistoreBidAdapter.js index 5c66be10804..0d63c00eb75 100644 --- a/modules/proxistoreBidAdapter.js +++ b/modules/proxistoreBidAdapter.js @@ -1,185 +1,160 @@ -import { isFn, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { deepSetValue } from '../src/utils.js'; const BIDDER_CODE = 'proxistore'; const PROXISTORE_VENDOR_ID = 418; -const COOKIE_BASE_URL = 'https://abs.proxistore.com/v3/rtb/prebid/multi'; -const COOKIE_LESS_URL = - 'https://abs.cookieless-proxistore.com/v3/rtb/prebid/multi'; - -function _createServerRequest(bidRequests, bidderRequest) { - var sizeIds = []; - bidRequests.forEach(function (bid) { - var sizeId = { - id: bid.bidId, - sizes: bid.sizes.map(function (size) { - return { - width: size[0], - height: size[1], - }; - }), - floor: _assignFloor(bid), - segments: _assignSegments(bid), - }; - sizeIds.push(sizeId); - }); - var payload = { - // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - auctionId: bidRequests[0].auctionId, - transactionId: bidRequests[0].ortb2Imp?.ext?.tid, - bids: sizeIds, - website: bidRequests[0].params.website, - language: bidRequests[0].params.language, - gdpr: { - applies: false, - consentGiven: false, - }, - }; +const COOKIE_BASE_URL = 'https://abs.proxistore.com/v3/rtb/openrtb'; +const COOKIE_LESS_URL = 'https://abs.cookieless-proxistore.com/v3/rtb/openrtb'; +const SYNC_BASE_URL = 'https://abs.proxistore.com/v3/rtb/sync'; + +const converter = ortbConverter({ + context: { + mediaType: BANNER, + netRevenue: true, + ttl: 30, + currency: 'EUR', + }, + request(buildRequest, imps, bidderRequest, context) { + const request = buildRequest(imps, bidderRequest, context); + const bidRequests = context.bidRequests; + if (bidRequests && bidRequests.length > 0) { + const params = bidRequests[0].params; + if (params.website) { + deepSetValue(request, 'ext.proxistore.website', params.website); + } + if (params.language) { + deepSetValue(request, 'ext.proxistore.language', params.language); + } + } + return request; + } +}); - if (bidderRequest && bidderRequest.gdprConsent) { - var gdprConsent = bidderRequest.gdprConsent; +/** + * Determines whether or not the given bid request is valid. + * + * @param bid The bid params to validate. + * @return boolean True if this is a valid bid, and false otherwise. + */ +function isBidRequestValid(bid) { + return !!(bid.params.website && bid.params.language); +} - if ( - typeof gdprConsent.gdprApplies === 'boolean' && - gdprConsent.gdprApplies - ) { - payload.gdpr.applies = true; - } +/** + * Make a server request from the list of BidRequests. + * + * @param bidRequests - an array of bids + * @param bidderRequest + * @return ServerRequest Info describing the request to the server. + */ +function buildRequests(bidRequests, bidderRequest) { + let gdprApplies = false; + let consentGiven = false; + + if (bidderRequest && bidderRequest.gdprConsent) { + const gdprConsent = bidderRequest.gdprConsent; - if ( - typeof gdprConsent.consentString === 'string' && - gdprConsent.consentString - ) { - payload.gdpr.consentString = bidderRequest.gdprConsent.consentString; + if (typeof gdprConsent.gdprApplies === 'boolean' && gdprConsent.gdprApplies) { + gdprApplies = true; } if (gdprConsent.vendorData) { - var vendorData = gdprConsent.vendorData; - + const vendorData = gdprConsent.vendorData; if ( vendorData.vendor && vendorData.vendor.consents && - typeof vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)] !== - 'undefined' + vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)] !== 'undefined' ) { - payload.gdpr.consentGiven = - !!vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)]; + consentGiven = !!vendorData.vendor.consents[PROXISTORE_VENDOR_ID.toString(10)]; } } } - var options = { + const options = { contentType: 'application/json', - withCredentials: payload.gdpr.consentGiven, + withCredentials: consentGiven, customHeaders: { - version: '1.0.4', + version: '2.0.0', }, }; - var endPointUri = - payload.gdpr.consentGiven || !payload.gdpr.applies - ? COOKIE_BASE_URL - : COOKIE_LESS_URL; + + const endPointUri = consentGiven || !gdprApplies ? COOKIE_BASE_URL : COOKIE_LESS_URL; return { method: 'POST', url: endPointUri, - data: JSON.stringify(payload), + data: converter.toORTB({ bidRequests, bidderRequest }), options: options, }; } -function _assignSegments(bid) { - var segs = (bid.ortb2 && bid.ortb2.user && bid.ortb2.user.ext && bid.ortb2.user.ext.data && bid.ortb2.user.ext.data.sd_rtd && bid.ortb2.user.ext.data.sd_rtd.segments ? bid.ortb2.user.ext.data.sd_rtd.segments : []); - var cats = {}; - if (bid.ortb2 && bid.ortb2.site && bid.ortb2.site.ext && bid.ortb2.site.ext.data && bid.ortb2.site.ext.data.sd_rtd) { - if (bid.ortb2.site.ext.data.sd_rtd.categories) { - segs = segs.concat(bid.ortb2.site.ext.data.sd_rtd.categories); - } - if (bid.ortb2.site.ext.data.sd_rtd.categories_score) { - cats = bid.ortb2.site.ext.data.sd_rtd.categories_score; - } - } - - return { - segments: segs, - contextual_categories: cats - }; -} - -function _createBidResponse(response) { - return { - requestId: response.requestId, - cpm: response.cpm, - width: response.width, - height: response.height, - ad: response.ad, - ttl: response.ttl, - creativeId: response.creativeId, - currency: response.currency, - netRevenue: response.netRevenue, - vastUrl: response.vastUrl, - vastXml: response.vastXml, - dealId: response.dealId, - meta: response.meta, - }; -} /** - * Determines whether or not the given bid request is valid. + * Unpack the response from the server into a list of bids. * - * @param bid The bid params to validate. - * @return boolean True if this is a valid bid, and false otherwise. + * @param response + * @param request + * @return An array of bids which were nested inside the server. */ - -function isBidRequestValid(bid) { - return !!(bid.params.website && bid.params.language); +function interpretResponse(response, request) { + if (response.body) { + return converter.fromORTB({ response: response.body, request: request.data }).bids; + } + return []; } -/** - * Make a server request from the list of BidRequests. - * - * @param bidRequests - an array of bids - * @param bidderRequest - * @return ServerRequest Info describing the request to the server. - */ - -function buildRequests(bidRequests, bidderRequest) { - var request = _createServerRequest(bidRequests, bidderRequest); - return request; -} /** - * Unpack the response from the server into a list of bids. + * Register user sync pixels and iframes. * - * @param serverResponse A successful response from the server. - * @param bidRequest Request original server request - * @return An array of bids which were nested inside the server. + * @param syncOptions - which sync types are enabled + * @param responses - server responses + * @param gdprConsent - GDPR consent data + * @return Array of sync objects */ +function getUserSyncs(syncOptions, responses, gdprConsent) { + const syncs = []; -function interpretResponse(serverResponse, bidRequest) { - return serverResponse.body.map(_createBidResponse); -} + // Only sync if consent given or GDPR doesn't apply + const consentGiven = gdprConsent?.vendorData?.vendor?.consents?.[PROXISTORE_VENDOR_ID]; + if (gdprConsent?.gdprApplies && !consentGiven) { + return syncs; + } -function _assignFloor(bid) { - if (!isFn(bid.getFloor)) { - return bid.params.bidFloor ? bid.params.bidFloor : null; + const params = new URLSearchParams(); + if (gdprConsent) { + params.set('gdpr', gdprConsent.gdprApplies ? '1' : '0'); + if (gdprConsent.consentString) { + params.set('gdpr_consent', gdprConsent.consentString); + } + } + + if (syncOptions.pixelEnabled) { + syncs.push({ + type: 'image', + url: `${SYNC_BASE_URL}/image?${params}` + }); } - const floor = bid.getFloor({ - currency: 'EUR', - mediaType: 'banner', - size: '*', - }); - if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'EUR') { - return floor.floor; + if (syncOptions.iframeEnabled) { + syncs.push({ + type: 'iframe', + url: `${SYNC_BASE_URL}/iframe?${params}` + }); } - return null; + + return syncs; } export const spec = { code: BIDDER_CODE, + gvlid: PROXISTORE_VENDOR_ID, isBidRequestValid: isBidRequestValid, buildRequests: buildRequests, interpretResponse: interpretResponse, - gvlid: PROXISTORE_VENDOR_ID, + getUserSyncs: getUserSyncs, + supportedMediaTypes: [BANNER], + browsingTopics: true, }; registerBidder(spec); diff --git a/modules/pubProvidedIdSystem.js b/modules/pubProvidedIdSystem.js index d23d992e495..bb802fce8c3 100644 --- a/modules/pubProvidedIdSystem.js +++ b/modules/pubProvidedIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; +import { submodule } from '../src/hook.js'; import { logInfo, isArray } from '../src/utils.js'; -import {VENDORLESS_GVLID} from '../src/consentHandler.js'; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -33,7 +33,7 @@ export const pubProvidedIdSubmodule = { * @returns {{pubProvidedId: Array}} or undefined if value doesn't exists */ decode(value) { - const res = value ? {pubProvidedId: value} : undefined; + const res = value ? { pubProvidedId: value } : undefined; logInfo('PubProvidedId: Decoded value ' + JSON.stringify(res)); return res; }, @@ -53,7 +53,7 @@ export const pubProvidedIdSubmodule = { if (typeof configParams.eidsFunction === 'function') { res = res.concat(configParams.eidsFunction()); } - return {id: res}; + return { id: res }; } }; diff --git a/modules/pubgeniusBidAdapter.js b/modules/pubgeniusBidAdapter.js index 6267d0c9225..bfdca074e2c 100644 --- a/modules/pubgeniusBidAdapter.js +++ b/modules/pubgeniusBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { deepAccess, deepSetValue, @@ -21,7 +21,7 @@ const BASE_URL = 'https://auction.adpearl.io'; export const spec = { code: 'pubgenius', - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], isBidRequestValid(bid) { const adUnitId = bid.params.adUnitId; diff --git a/modules/publicGoodBidAdapter.js b/modules/publicGoodBidAdapter.js index b5fa56d7a53..d968cf93c5c 100644 --- a/modules/publicGoodBidAdapter.js +++ b/modules/publicGoodBidAdapter.js @@ -1,7 +1,7 @@ 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; const BIDDER_CODE = 'publicgood'; const PUBLIC_GOOD_ENDPOINT = 'https://advice.pgs.io'; @@ -67,7 +67,7 @@ export const spec = { bidResponse.currency = 'USD'; bidResponse.netRevenue = true; bidResponse.ttl = 360; - bidResponse.meta = {advertiserDomains: []}; + bidResponse.meta = { advertiserDomains: [] }; bidResponses.push(bidResponse); } diff --git a/modules/publinkIdSystem.js b/modules/publinkIdSystem.js index 09981498877..7554a0e9c38 100644 --- a/modules/publinkIdSystem.js +++ b/modules/publinkIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { ajax } from '../src/ajax.js'; import { parseUrl, buildUrl, logError } from '../src/utils.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -25,7 +25,7 @@ const PUBLINK_S2S_COOKIE = '_publink_srv'; const PUBLINK_REQUEST_PATH = '/cvx/client/sync/publink'; const PUBLINK_REFRESH_PATH = '/cvx/client/sync/publink/refresh'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function isHex(s) { return /^[A-F0-9]+$/i.test(s); @@ -69,7 +69,7 @@ function publinkIdUrl(params, consentData, storedId) { function makeCallback(config = {}, consentData, storedId) { return function(prebidCallback) { - const options = {method: 'GET', withCredentials: true}; + const options = { method: 'GET', withCredentials: true }; const handleResponse = function(responseText, xhr) { if (xhr.status === 200) { const response = JSON.parse(responseText); @@ -136,7 +136,7 @@ export const publinkIdSubmodule = { * @returns {{publinkId: string} | undefined} */ decode(publinkId) { - return {publinkId: publinkId}; + return { publinkId: publinkId }; }, /** @@ -151,9 +151,9 @@ export const publinkIdSubmodule = { getId: function(config, consentData, storedId) { const localValue = getlocalValue(); if (localValue) { - return {id: localValue}; + return { id: localValue }; } - return {callback: makeCallback(config, consentData, storedId)}; + return { callback: makeCallback(config, consentData, storedId) }; }, eids: { 'publinkId': { diff --git a/modules/pubmaticAnalyticsAdapter.js b/modules/pubmaticAnalyticsAdapter.js index 19b1c11ffe9..04838ef6989 100755 --- a/modules/pubmaticAnalyticsAdapter.js +++ b/modules/pubmaticAnalyticsAdapter.js @@ -524,7 +524,7 @@ const eventHandlers = { /// /////////// ADAPTER DEFINITION ////////////// -const baseAdapter = adapter({analyticsType: 'endpoint'}); +const baseAdapter = adapter({ analyticsType: 'endpoint' }); const pubmaticAdapter = Object.assign({}, baseAdapter, { enableAnalytics(conf = {}) { diff --git a/modules/pubmaticBidAdapter.js b/modules/pubmaticBidAdapter.js index f23665670e9..5d85d4b8dca 100644 --- a/modules/pubmaticBidAdapter.js +++ b/modules/pubmaticBidAdapter.js @@ -315,7 +315,7 @@ const setFloorInImp = (imp, bid) => { const mediaTypeFloor = parseFloat(floorInfo.floor); if (isMultiFormatRequest && mediaType !== BANNER) { logInfo(LOG_WARN_PREFIX, 'floor from floor module returned for mediatype:', mediaType, 'is : ', mediaTypeFloor, 'with currency :', imp.bidfloorcur); - imp[mediaType]['ext'] = {'bidfloor': mediaTypeFloor, 'bidfloorcur': imp.bidfloorcur}; + imp[mediaType]['ext'] = { 'bidfloor': mediaTypeFloor, 'bidfloorcur': imp.bidfloorcur }; } logInfo(LOG_WARN_PREFIX, 'floor from floor module:', mediaTypeFloor, 'previous floor value', bidFloor, 'Min:', Math.min(mediaTypeFloor, bidFloor)); bidFloor = bidFloor === -1 ? mediaTypeFloor : Math.min(mediaTypeFloor, bidFloor); @@ -323,7 +323,7 @@ const setFloorInImp = (imp, bid) => { } }); if (isMultiFormatRequest && mediaType === BANNER) { - imp[mediaType]['ext'] = {'bidfloor': bidFloor, 'bidfloorcur': imp.bidfloorcur}; + imp[mediaType]['ext'] = { 'bidfloor': bidFloor, 'bidfloorcur': imp.bidfloorcur }; } }); } @@ -756,6 +756,7 @@ export const spec = { code: BIDDER_CODE, gvlid: 76, supportedMediaTypes: [BANNER, VIDEO, NATIVE], + alwaysHasCapacity: true, /** * Determines whether or not the given bid request is valid. Valid bid request must have placementId and hbid * diff --git a/modules/pubstackBidAdapter.md b/modules/pubstackBidAdapter.md new file mode 100644 index 00000000000..dc3df3b8ee5 --- /dev/null +++ b/modules/pubstackBidAdapter.md @@ -0,0 +1,30 @@ +# Overview +``` +Module Name: Pubstack Bidder Adapter +Module Type: Bidder Adapter +Maintainer: prebid@pubstack.io +``` + +# Description +Connects to Pubstack exchange for bids. + +Pubstack bid adapter supports all media type including video, banner and native. + +# Test Parameters +``` +var adUnits = [{ + code: 'adunit-1', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bids: [{ + bidder: 'pubstack', + params: { + siteId: 'your-site-id', + adUnitName: 'adunit-1' + } + }] +}]; +``` \ No newline at end of file diff --git a/modules/pubstackBidAdapter.ts b/modules/pubstackBidAdapter.ts new file mode 100644 index 00000000000..b43ca7be4b8 --- /dev/null +++ b/modules/pubstackBidAdapter.ts @@ -0,0 +1,156 @@ +import { canAccessWindowTop, deepSetValue, getWindowSelf, getWindowTop, logError } from '../src/utils.js'; +import { AdapterRequest, BidderSpec, registerBidder, ServerResponse } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { getPlacementPositionUtils } from '../libraries/placementPositionInfo/placementPositionInfo.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; +import { BidRequest, ClientBidderRequest } from '../src/adapterManager.js'; +import { ORTBRequest } from '../src/prebid.public.js'; +import { config } from '../src/config.js'; +import { SyncType } from '../src/userSync.js'; +import { ConsentData, CONSENT_GDPR, CONSENT_USP, CONSENT_GPP } from '../src/consentHandler.js'; +import { getGlobal } from '../src/prebidGlobal.js'; + +const BIDDER_CODE = 'pubstack'; +const GVLID = 1408; +const REQUEST_URL = 'https://node.pbstck.com/openrtb2/auction'; +const COOKIESYNC_IFRAME_URL = 'https://cdn.pbstck.com/async_usersync.html'; +const COOKIESYNC_PIXEL_URL = 'https://cdn.pbstck.com/async_usersync.png'; + +declare module '../src/adUnits' { + interface BidderParams { + [BIDDER_CODE]: { + siteId: string; + adUnitName: string; + }; + } +} + +type GetUserSyncFn = ( + syncOptions: { + iframeEnabled: boolean; + pixelEnabled: boolean; + }, + responses: ServerResponse[], + gdprConsent: null | ConsentData[typeof CONSENT_GDPR], + uspConsent: null | ConsentData[typeof CONSENT_USP], + gppConsent: null | ConsentData[typeof CONSENT_GPP]) => ({ type: SyncType, url: string })[] + +const siteIds: Set = new Set(); +let cntRequest = 0; +let cntTimeouts = 0; +const { getPlacementEnv, getPlacementInfo } = getPlacementPositionUtils(); + +const getElementForAdUnitCode = (adUnitCode: string): HTMLElement | undefined => { + if (!adUnitCode) return; + const win = canAccessWindowTop() ? getWindowTop() : getWindowSelf(); + const doc = win?.document; + let element = doc?.getElementById(adUnitCode) as HTMLElement | null; + if (element) return element; + const divId = getGptSlotInfoForAdUnitCode(adUnitCode)?.divId; + element = divId ? doc?.getElementById(divId) as HTMLElement | null : null; + if (element) return element; +}; + +const converter = ortbConverter({ + imp(buildImp, bidRequest: BidRequest, context) { + const element = getElementForAdUnitCode(bidRequest.adUnitCode); + const placementInfo = getPlacementInfo(bidRequest); + const imp = buildImp(bidRequest, context); + deepSetValue(imp, `ext.prebid.bidder.${BIDDER_CODE}.adUnitName`, bidRequest.params.adUnitName); + deepSetValue(imp, `ext.prebid.placement.code`, bidRequest.adUnitCode); + deepSetValue(imp, `ext.prebid.placement.domId`, element?.id); + deepSetValue(imp, `ext.prebid.placement.viewability`, placementInfo.PlacementPercentView); + deepSetValue(imp, `ext.prebid.placement.viewportDistance`, placementInfo.DistanceToView); + deepSetValue(imp, `ext.prebid.placement.height`, placementInfo.ElementHeight); + deepSetValue(imp, `ext.prebid.placement.auctionsCount`, placementInfo.AuctionsCount); + return imp; + }, + request(buildRequest, imps, bidderRequest, context) { + cntRequest++; + const placementEnv = getPlacementEnv(); + const request = buildRequest(imps, bidderRequest, context) + const siteId = bidderRequest.bids[0].params.siteId + siteIds.add(siteId); + deepSetValue(request, 'site.publisher.id', siteId); + deepSetValue(request, 'test', config.getConfig('debug') ? 1 : 0); + deepSetValue(request, 'ext.prebid.version', getGlobal()?.version ?? 'unknown'); + deepSetValue(request, `ext.prebid.request.count`, cntRequest); + deepSetValue(request, `ext.prebid.request.timeoutCount`, cntTimeouts); + deepSetValue(request, `ext.prebid.page.tabActive`, placementEnv.TabActive); + deepSetValue(request, `ext.prebid.page.height`, placementEnv.PageHeight); + deepSetValue(request, `ext.prebid.page.viewportHeight`, placementEnv.ViewportHeight); + deepSetValue(request, `ext.prebid.page.timeFromNavigation`, placementEnv.TimeFromNavigation); + return request; + }, +}); + +const isBidRequestValid = (bid: BidRequest): boolean => { + if (!bid.params.siteId || typeof bid.params.siteId !== 'string') { + logError('bid.params.siteId needs to be a string'); + if (config.getConfig('debug') === false) return false; + } + if (!bid.params.adUnitName || typeof bid.params.adUnitName !== 'string') { + logError('bid.params.adUnitName needs to be a string'); + if (config.getConfig('debug') === false) return false; + } + return true; +}; + +const buildRequests = ( + bidRequests: BidRequest[], + bidderRequest: ClientBidderRequest, +): AdapterRequest => { + const data: ORTBRequest = converter.toORTB({ bidRequests, bidderRequest }); + const siteId = data.site.publisher.id; + return { + method: 'POST', + url: `${REQUEST_URL}?siteId=${siteId}`, + data, + }; +}; + +const interpretResponse = (serverResponse, bidRequest) => { + if (!serverResponse?.body) { + return []; + } + return converter.fromORTB({ request: bidRequest.data, response: serverResponse.body }); +}; + +const getUserSyncs: GetUserSyncFn = (syncOptions, _serverResponses, gdprConsent, uspConsent, gppConsent) => { + const isIframeEnabled = syncOptions.iframeEnabled; + const isPixelEnabled = syncOptions.pixelEnabled; + + if (!isIframeEnabled && !isPixelEnabled) { + return []; + } + + const payload = btoa(JSON.stringify({ + gdprConsentString: gdprConsent?.consentString, + gdprApplies: gdprConsent?.gdprApplies, + uspConsent, + gpp: gppConsent?.gppString, + gpp_sid: gppConsent?.applicableSections + + })); + const syncUrl = isIframeEnabled ? COOKIESYNC_IFRAME_URL : COOKIESYNC_PIXEL_URL; + + return Array.from(siteIds).map(siteId => ({ + type: isIframeEnabled ? 'iframe' : 'image', + url: `${syncUrl}?consent=${payload}&siteId=${siteId}`, + })); +}; + +export const spec: BidderSpec = { + code: BIDDER_CODE, + aliases: [ {code: `${BIDDER_CODE}_server`, gvlid: GVLID} ], + gvlid: GVLID, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + isBidRequestValid, + buildRequests, + interpretResponse, + getUserSyncs, + onTimeout: () => cntTimeouts++, +}; + +registerBidder(spec); diff --git a/modules/pubwiseAnalyticsAdapter.js b/modules/pubwiseAnalyticsAdapter.js index f92c61a53dd..51cc3b413e5 100644 --- a/modules/pubwiseAnalyticsAdapter.js +++ b/modules/pubwiseAnalyticsAdapter.js @@ -1,12 +1,12 @@ import { getParameterByName, logInfo, generateUUID, debugTurnedOn } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'pubwise'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); /**** * PubWise.io Analytics @@ -32,10 +32,10 @@ const analyticsType = 'endpoint'; const analyticsName = 'PubWise:'; const prebidVersion = '$prebid.version$'; const pubwiseVersion = '4.0.1'; -let configOptions = {site: '', endpoint: 'https://api.pubwise.io/api/v5/event/add/', debug: null}; +let configOptions = { site: '', endpoint: 'https://api.pubwise.io/api/v5/event/add/', debug: null }; let pwAnalyticsEnabled = false; -const utmKeys = {utm_source: '', utm_medium: '', utm_campaign: '', utm_term: '', utm_content: ''}; -const sessionData = {sessionId: '', activationId: ''}; +const utmKeys = { utm_source: '', utm_medium: '', utm_campaign: '', utm_term: '', utm_content: '' }; +const sessionData = { sessionId: '', activationId: '' }; const pwNamespace = 'pubwise'; const pwEvents = []; let metaData = {}; @@ -168,7 +168,7 @@ function sessionExpired() { function flushEvents() { if (pwEvents.length > 0) { - const dataBag = {metaData: metaData, eventList: pwEvents.splice(0)}; // put all the events together with the metadata and send + const dataBag = { metaData: metaData, eventList: pwEvents.splice(0) }; // put all the events together with the metadata and send ajax(configOptions.endpoint, (result) => pwInfo(`Result`, result), JSON.stringify(dataBag)); } } @@ -254,9 +254,9 @@ function filterAuctionInit(data) { return modified; } -const pubwiseAnalytics = Object.assign(adapter({analyticsType}), { +const pubwiseAnalytics = Object.assign(adapter({ analyticsType }), { // Override AnalyticsAdapter functions by supplying custom methods - track({eventType, args}) { + track({ eventType, args }) { this.handleEvent(eventType, args); } }); diff --git a/modules/pulsepointBidAdapter.js b/modules/pulsepointBidAdapter.js index 9619488f261..2d4bcc1abf9 100644 --- a/modules/pulsepointBidAdapter.js +++ b/modules/pulsepointBidAdapter.js @@ -29,7 +29,7 @@ export const spec = { ), buildRequests: (bidRequests, bidderRequest) => { - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); return { method: 'POST', url: 'https://bid.contextweb.com/header/ortb?src=prebid', @@ -40,7 +40,7 @@ export const spec = { interpretResponse: (response, request) => { if (response.body) { - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; } return []; }, diff --git a/modules/pwbidBidAdapter.js b/modules/pwbidBidAdapter.js index cb383fee630..eaa06107b39 100644 --- a/modules/pwbidBidAdapter.js +++ b/modules/pwbidBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { _each, isBoolean, isNumber, isStr, deepClone, isArray, deepSetValue, inIframe, mergeDeep, deepAccess, logMessage, logInfo, logWarn, logError, isPlainObject } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; @@ -275,7 +275,7 @@ export const spec = { deepSetValue(payload, 'regs.coppa', 1); } - var options = {contentType: 'text/plain'}; + var options = { contentType: 'text/plain' }; _logInfo('buildRequests payload', payload); _logInfo('buildRequests bidderRequest', bidderRequest); diff --git a/modules/pxyzBidAdapter.js b/modules/pxyzBidAdapter.js index 12bd04c744d..681055d78b9 100644 --- a/modules/pxyzBidAdapter.js +++ b/modules/pxyzBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {isArray, logError, logInfo} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { isArray, logError, logInfo } from '../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/qortexRtdProvider.js b/modules/qortexRtdProvider.js index 8049f02be81..4b2ad2447e3 100644 --- a/modules/qortexRtdProvider.js +++ b/modules/qortexRtdProvider.js @@ -83,7 +83,7 @@ export function addContextToRequests (reqBidsConfig) { if (checkPercentageOutcome(qortexSessionInfo.groupConfig?.prebidBidEnrichmentPercentage)) { const fragment = qortexSessionInfo.currentSiteContext if (qortexSessionInfo.bidderArray?.length > 0) { - qortexSessionInfo.bidderArray.forEach(bidder => mergeDeep(reqBidsConfig.ortb2Fragments.bidder, {[bidder]: fragment})); + qortexSessionInfo.bidderArray.forEach(bidder => mergeDeep(reqBidsConfig.ortb2Fragments.bidder, { [bidder]: fragment })); } else if (!qortexSessionInfo.bidderArray) { mergeDeep(reqBidsConfig.ortb2Fragments.global, fragment); } else { @@ -101,7 +101,7 @@ export function loadScriptTag(config) { const code = 'qortex'; const groupId = config.params.groupId; const src = 'https://tags.qortex.ai/bootstrapper' - const attr = {'data-group-id': groupId} + const attr = { 'data-group-id': groupId } const tc = config.params.tagConfig Object.keys(tc).forEach(p => { @@ -117,7 +117,7 @@ export function loadScriptTag(config) { } switch (e?.detail?.type) { case 'qx-impression': - const {uid} = e.detail; + const { uid } = e.detail; if (!uid || qortexSessionInfo.impressionIds.has(uid)) { logWarn(`Received invalid billable event due to ${!uid ? 'missing' : 'duplicate'} uid: qx-impression`) return; @@ -162,7 +162,7 @@ export function requestContextData() { * @param {Object} config module config obtained during init */ export function initializeModuleData(config) { - const {groupId, bidders, enableBidEnrichment} = config.params; + const { groupId, bidders, enableBidEnrichment } = config.params; qortexSessionInfo.bidEnrichmentDisabled = enableBidEnrichment !== null ? !enableBidEnrichment : true; qortexSessionInfo.bidderArray = bidders; qortexSessionInfo.impressionIds = new Set(); diff --git a/modules/quantcastBidAdapter.js b/modules/quantcastBidAdapter.js index 0ee58a927d1..e8dc9ff6852 100644 --- a/modules/quantcastBidAdapter.js +++ b/modules/quantcastBidAdapter.js @@ -1,9 +1,9 @@ -import {deepAccess, isArray, isEmpty, logError, logInfo} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {parseDomain} from '../src/refererDetection.js'; +import { deepAccess, isArray, isEmpty, logError, logInfo } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { parseDomain } from '../src/refererDetection.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -26,7 +26,7 @@ export const QUANTCAST_PROTOCOL = 'https'; export const QUANTCAST_PORT = '8443'; export const QUANTCAST_FPA = '__qca'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); function makeVideoImp(bid) { const videoInMediaType = deepAccess(bid, 'mediaTypes.video') || {}; @@ -136,7 +136,7 @@ export const spec = { const uspConsent = deepAccess(bidderRequest, 'uspConsent'); const referrer = deepAccess(bidderRequest, 'refererInfo.ref'); const page = deepAccess(bidderRequest, 'refererInfo.page') || deepAccess(window, 'location.href'); - const domain = parseDomain(page, {noLeadingWww: true}); + const domain = parseDomain(page, { noLeadingWww: true }); // Check for GDPR consent for purpose 1, and drop request if consent has not been given // Remaining consent checks are performed server-side. diff --git a/modules/quantcastIdSystem.js b/modules/quantcastIdSystem.js index aeccceb0d10..4b4d7b97d40 100644 --- a/modules/quantcastIdSystem.js +++ b/modules/quantcastIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js' -import {getStorageManager} from '../src/storageManager.js'; +import { submodule } from '../src/hook.js' +import { getStorageManager } from '../src/storageManager.js'; import { triggerPixel, logInfo } from '../src/utils.js'; import { uspDataHandler, coppaDataHandler, gdprDataHandler } from '../src/adapterManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -30,7 +30,7 @@ const GDPR_PRIVACY_STRING = gdprDataHandler.getConsentData(); const US_PRIVACY_STRING = uspDataHandler.getConsentData(); const MODULE_NAME = 'quantcastId'; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); export function firePixel(clientId, cookieExpDays = DEFAULT_COOKIE_EXP_DAYS) { // check for presence of Quantcast Measure tag _qevent obj and publisher provided clientID diff --git a/modules/r2b2AnalyticsAdapter.js b/modules/r2b2AnalyticsAdapter.js index f8953232982..f452e97e094 100644 --- a/modules/r2b2AnalyticsAdapter.js +++ b/modules/r2b2AnalyticsAdapter.js @@ -1,11 +1,11 @@ -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {EVENTS} from '../src/constants.js'; +import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {isNumber, isPlainObject, isStr, logError, logWarn} from '../src/utils.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {config} from '../src/config.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { isNumber, isPlainObject, isStr, logError, logWarn } from '../src/utils.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { config } from '../src/config.js'; const ADAPTER_VERSION = '1.1.0'; const ADAPTER_CODE = 'r2b2'; @@ -357,9 +357,9 @@ function handleBidderDone (args) { } function getAuctionUnitsData (auctionObject) { let unitsData = {}; - const {bidsReceived, bidsRejected} = auctionObject; + const { bidsReceived, bidsRejected } = auctionObject; const _unitsDataBidReducer = function(data, bid, key) { - const {adUnitCode, bidder} = bid; + const { adUnitCode, bidder } = bid; data[adUnitCode] = data[adUnitCode] || {}; data[adUnitCode][key] = data[adUnitCode][key] || {}; data[adUnitCode][key][bidder] = (data[adUnitCode][key][bidder] || 0) + 1; @@ -472,7 +472,7 @@ function handleStaleRender (args) { } function handleRenderSuccess (args) { // console.log('render success:', arguments); - const {bid} = args; + const { bid } = args; bidsData[bid.adId].renderTime = Date.now(); const data = { b: bid.bidder, @@ -488,7 +488,7 @@ function handleRenderSuccess (args) { } function handleRenderFailed (args) { // console.log('render failed:', arguments); - const {bid, reason} = args; + const { bid, reason } = args; const data = { b: bid.bidder, u: bid.adUnitCode, @@ -513,7 +513,7 @@ function handleBidViewable (args) { processEvent(event); } -const baseAdapter = adapter({analyticsType}); +const baseAdapter = adapter({ analyticsType }); const r2b2Analytics = Object.assign({}, baseAdapter, { getUrl() { return `${DEFAULT_PROTOCOL}://${LOG_SERVER}/${DEFAULT_EVENT_PATH}` @@ -523,7 +523,7 @@ const r2b2Analytics = Object.assign({}, baseAdapter, { }, enableAnalytics(conf = {}) { if (isPlainObject(conf.options)) { - const {domain, configId, configVer, server} = conf.options; + const { domain, configId, configVer, server } = conf.options; if (!domain || !isStr(domain)) { logWarn(`${MODULE_NAME}: Mandatory parameter 'domain' not configured, analytics disabled`); return @@ -554,7 +554,7 @@ const r2b2Analytics = Object.assign({}, baseAdapter, { baseAdapter.enableAnalytics.call(this, conf); }, track(event) { - const {eventType, args} = event; + const { eventType, args } = event; try { if (!adServerCurrency) { const currencyObj = config.getConfig('currency'); diff --git a/modules/r2b2BidAdapter.js b/modules/r2b2BidAdapter.js index bb645d49e8c..2acca14cc78 100644 --- a/modules/r2b2BidAdapter.js +++ b/modules/r2b2BidAdapter.js @@ -1,10 +1,10 @@ -import {logWarn, logError, triggerPixel, deepSetValue, getParameterByName} from '../src/utils.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; -import {pbsExtensions} from '../libraries/pbsExtensions/pbsExtensions.js'; -import {bidderSettings} from '../src/bidderSettings.js'; +import { logWarn, logError, triggerPixel, deepSetValue, getParameterByName } from '../src/utils.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; +import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js'; +import { bidderSettings } from '../src/bidderSettings.js'; const ADAPTER_VERSION = '1.0.0'; const BIDDER_CODE = 'r2b2'; @@ -243,14 +243,14 @@ export const spec = { const responseImpId = responseBid.impid; const requestCurrentImp = requestImps.find((requestImp) => requestImp.id === responseImpId); if (!requestCurrentImp) { - r2b2Error('Cant match bid response.', {impid: Boolean(responseBid.impid)}); + r2b2Error('Cant match bid response.', { impid: Boolean(responseBid.impid) }); continue;// Skip this iteration if there's no match } prebidResponses.push(createPrebidResponseBid(requestCurrentImp, responseBid, response, request.bids)); } }) } catch (e) { - r2b2Error('Error while interpreting response:', {msg: e.message}); + r2b2Error('Error while interpreting response:', { msg: e.message }); } return prebidResponses; }, diff --git a/modules/raveltechRtdProvider.js b/modules/raveltechRtdProvider.js index adac49c3258..72110c20603 100644 --- a/modules/raveltechRtdProvider.js +++ b/modules/raveltechRtdProvider.js @@ -1,6 +1,6 @@ -import {submodule, getHook} from '../src/hook.js'; +import { submodule, getHook } from '../src/hook.js'; import adapterManager from '../src/adapterManager.js'; -import {logInfo, deepClone, isArray, isStr, isPlainObject, logError} from '../src/utils.js'; +import { logInfo, deepClone, isArray, isStr, isPlainObject, logError } from '../src/utils.js'; // Constants const MODULE_NAME = 'raveltech'; @@ -24,10 +24,10 @@ const getAnonymizedEids = (eids) => { return []; } logInfo('Anonymized as byte array of length=', id.length); - return [ { + return [{ ...uid, id - } ]; + }]; }) }) @@ -57,7 +57,7 @@ const wrapBuildRequests = (aliasName, preserveOriginalBid, buildRequests) => { } let requests = preserveOriginalBid ? buildRequests(validBidRequests, ...rest) : []; if (!isArray(requests)) { - requests = [ requests ]; + requests = [requests]; } try { @@ -73,7 +73,7 @@ const wrapBuildRequests = (aliasName, preserveOriginalBid, buildRequests) => { let ravelRequests = buildRequests(ravelBidRequests, ...rest); if (!isArray(ravelRequests) && ravelRequests) { - ravelRequests = [ ravelRequests ]; + ravelRequests = [ravelRequests]; } if (ravelRequests) { ravelRequests.forEach(request => { @@ -84,7 +84,7 @@ const wrapBuildRequests = (aliasName, preserveOriginalBid, buildRequests) => { }) } - return [ ...requests ?? [], ...ravelRequests ?? [] ]; + return [...requests ?? [], ...ravelRequests ?? []]; } catch (e) { logError('Error while generating ravel requests :', e); return requests; diff --git a/modules/reconciliationRtdProvider.js b/modules/reconciliationRtdProvider.js index 46486923c0a..11074b9a286 100644 --- a/modules/reconciliationRtdProvider.js +++ b/modules/reconciliationRtdProvider.js @@ -16,9 +16,9 @@ * @property {?boolean} allowAccess */ -import {submodule} from '../src/hook.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import {generateUUID, isGptPubadsDefined, logError, timestamp} from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { generateUUID, isGptPubadsDefined, logError, timestamp } from '../src/utils.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -27,7 +27,8 @@ import {generateUUID, isGptPubadsDefined, logError, timestamp} from '../src/util /** @type {Object} */ const MessageType = { IMPRESSION_REQUEST: 'rsdk:impression:req', - IMPRESSION_RESPONSE: 'rsdk:impression:res'}; + IMPRESSION_RESPONSE: 'rsdk:impression:res' +}; /** @type {ModuleParams} */ const DEFAULT_PARAMS = { initUrl: 'https://confirm.fiduciadlt.com/init', diff --git a/modules/relaidoBidAdapter.js b/modules/relaidoBidAdapter.js index 1ef3be58798..2423bf69149 100644 --- a/modules/relaidoBidAdapter.js +++ b/modules/relaidoBidAdapter.js @@ -23,7 +23,7 @@ const ADAPTER_VERSION = '1.2.2'; const DEFAULT_TTL = 300; const UUID_KEY = 'relaido_uuid'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); function isBidRequestValid(bid) { if (!deepAccess(bid, 'params.placementId')) { diff --git a/modules/relevadRtdProvider.js b/modules/relevadRtdProvider.js index 41b2ee797e5..eba2fdde48a 100644 --- a/modules/relevadRtdProvider.js +++ b/modules/relevadRtdProvider.js @@ -6,11 +6,11 @@ * @requires module:modules/realTimeData */ -import {deepSetValue, isEmpty, logError, mergeDeep} from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import {config} from '../src/config.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { deepSetValue, isEmpty, logError, mergeDeep } from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { config } from '../src/config.js'; +import { getRefererInfo } from '../src/refererDetection.js'; const MODULE_NAME = 'realTimeData'; const SUBMODULE_NAME = 'RelevadRTDModule'; @@ -116,7 +116,7 @@ function composeOrtb2Data(rtdData, prefix) { const contentSegments = { name: 'relevad', ext: { segtax: content.segtax }, - segment: content.segs.map(x => { return {id: x}; }) + segment: content.segs.map(x => { return { id: x }; }) }; deepSetValue(addOrtb2, prefix + '.content.data', [contentSegments]); } @@ -174,7 +174,7 @@ function filterByScore(dict, minscore) { * @return {object} Filtered RTD */ function getFiltered(data, minscore) { - const relevadData = {'segments': []}; + const relevadData = { 'segments': [] }; minscore = minscore && typeof minscore === 'number' ? minscore : 30; @@ -182,11 +182,11 @@ function getFiltered(data, minscore) { const pcats = filterByScore(data.pcats, minscore) || cats; const scats = filterByScore(data.scats, minscore) || pcats; const cattax = (data.cattax || data.cattax === undefined) ? data.cattax : CATTAX_IAB; - relevadData.categories = {cat: cats, pagecat: pcats, sectioncat: scats, cattax: cattax}; + relevadData.categories = { cat: cats, pagecat: pcats, sectioncat: scats, cattax: cattax }; const contsegs = filterByScore(data.contsegs, minscore); const segtax = data.segtax ? data.segtax : SEGTAX_IAB; - relevadData.content = {segs: contsegs, segtax: segtax}; + relevadData.content = { segs: contsegs, segtax: segtax }; try { if (data && data.segments) { @@ -283,7 +283,7 @@ export function addRtdData(reqBids, data, moduleConfig) { }); }); - serverData = {...serverData, ...relevadData}; + serverData = { ...serverData, ...relevadData }; return adUnits; } @@ -329,7 +329,7 @@ function onAuctionEnd(auctionDetails, config, userConsent) { }); entries(adunitObj).forEach(([adunitCode, bidsReceived]) => { - adunits.push({code: adunitCode, bids: bidsReceived}); + adunits.push({ code: adunitCode, bids: bidsReceived }); }); const data = { diff --git a/modules/relevantdigitalBidAdapter.js b/modules/relevantdigitalBidAdapter.js index c776022749d..6e9a1a442d3 100644 --- a/modules/relevantdigitalBidAdapter.js +++ b/modules/relevantdigitalBidAdapter.js @@ -1,9 +1,9 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {pbsExtensions} from '../libraries/pbsExtensions/pbsExtensions.js' -import {deepSetValue, isEmpty, deepClone, shuffle, triggerPixel, deepAccess} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js' +import { deepSetValue, isEmpty, deepClone, shuffle, triggerPixel, deepAccess } from '../src/utils.js'; const BIDDER_CODE = 'relevantdigital'; @@ -111,7 +111,7 @@ export const spec = { buildRequests(bidRequests, bidderRequest) { const { bidder } = bidRequests[0]; const cfg = getBidderConfig(bidRequests); - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); /** Set tmax, in general this will be timeout - pbsBufferMs */ const pbjsTimeout = bidderRequest.timeout || 1000; @@ -147,11 +147,11 @@ export const spec = { Object.entries(MODIFIERS).forEach(([field, combineFn]) => { const obj = resp.ext?.[field]; if (!isEmpty(obj)) { - resp.ext[field] = {[bidder]: combineFn(Object.values(obj))}; + resp.ext[field] = { [bidder]: combineFn(Object.values(obj)) }; } }); - const bids = converter.fromORTB({response: resp, request: request.data}).bids; + const bids = converter.fromORTB({ response: resp, request: request.data }).bids; return bids; }, diff --git a/modules/responsiveAdsBidAdapter.js b/modules/responsiveAdsBidAdapter.js index a33a52f5644..b9e366958c4 100644 --- a/modules/responsiveAdsBidAdapter.js +++ b/modules/responsiveAdsBidAdapter.js @@ -1,4 +1,4 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { diff --git a/modules/retailspotBidAdapter.js b/modules/retailspotBidAdapter.js index 5e11e95787e..0b031d0e85d 100644 --- a/modules/retailspotBidAdapter.js +++ b/modules/retailspotBidAdapter.js @@ -1,6 +1,6 @@ -import {buildUrl, deepAccess, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { buildUrl, deepAccess, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/revantageBidAdapter.js b/modules/revantageBidAdapter.js new file mode 100644 index 00000000000..0a0186d5b59 --- /dev/null +++ b/modules/revantageBidAdapter.js @@ -0,0 +1,407 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepClone, deepAccess, logWarn, logError, triggerPixel } from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; + +const BIDDER_CODE = 'revantage'; +const ENDPOINT_URL = 'https://bid.revantage.io/bid'; +const SYNC_URL = 'https://sync.revantage.io/sync'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO], + + isBidRequestValid: function(bid) { + return !!(bid && bid.params && bid.params.feedId); + }, + + buildRequests: function(validBidRequests, bidderRequest) { + // Handle null/empty bid requests + if (!validBidRequests || validBidRequests.length === 0) { + return []; + } + + // All bid requests in a batch must have the same feedId + // If not, we log a warning and return an empty array + const feedId = validBidRequests[0]?.params?.feedId; + const allSameFeedId = validBidRequests.every(bid => bid.params.feedId === feedId); + if (!allSameFeedId) { + logWarn('Revantage: All bid requests in a batch must have the same feedId'); + return []; + } + + try { + const openRtbBidRequest = makeOpenRtbRequest(validBidRequests, bidderRequest); + return { + method: 'POST', + url: ENDPOINT_URL + '?feed=' + encodeURIComponent(feedId), + data: JSON.stringify(openRtbBidRequest), + options: { + contentType: 'text/plain', + withCredentials: false + }, + bidRequests: validBidRequests + }; + } catch (e) { + logError('Revantage: buildRequests failed', e); + return []; + } + }, + + interpretResponse: function(serverResponse, request) { + const bids = []; + const resp = serverResponse.body; + const originalBids = request.bidRequests || []; + const bidIdMap = {}; + originalBids.forEach(b => { bidIdMap[b.bidId] = b; }); + + if (!resp || !Array.isArray(resp.seatbid)) return bids; + + resp.seatbid.forEach(seatbid => { + if (Array.isArray(seatbid.bid)) { + seatbid.bid.forEach(rtbBid => { + const originalBid = bidIdMap[rtbBid.impid]; + if (!originalBid || !rtbBid.price || rtbBid.price <= 0) return; + + // Check for ad markup + const hasAdMarkup = !!(rtbBid.adm || rtbBid.vastXml || rtbBid.vastUrl); + if (!hasAdMarkup) { + logWarn('Revantage: No ad markup in bid'); + return; + } + + const bidResponse = { + requestId: originalBid.bidId, + cpm: rtbBid.price, + width: rtbBid.w || getFirstSize(originalBid, 0, 300), + height: rtbBid.h || getFirstSize(originalBid, 1, 250), + creativeId: rtbBid.crid || rtbBid.id || rtbBid.adid || 'revantage-' + Date.now(), + dealId: rtbBid.dealid, + currency: resp.cur || 'USD', + netRevenue: true, + ttl: 300, + meta: { + advertiserDomains: rtbBid.adomain || [], + dsp: seatbid.seat || 'unknown', + networkName: 'Revantage' + } + }; + + // Add burl for server-side win notification + if (rtbBid.burl) { + bidResponse.burl = rtbBid.burl; + } + + // Determine if this is a video bid + // FIX: Check for VAST content in adm even for multi-format ad units + const isVideo = (rtbBid.ext && rtbBid.ext.mediaType === 'video') || + rtbBid.vastXml || rtbBid.vastUrl || + isVastAdm(rtbBid.adm) || + (originalBid.mediaTypes && originalBid.mediaTypes.video && + !originalBid.mediaTypes.banner); + + if (isVideo) { + bidResponse.mediaType = VIDEO; + bidResponse.vastXml = rtbBid.vastXml || rtbBid.adm; + bidResponse.vastUrl = rtbBid.vastUrl; + + if (!bidResponse.vastUrl && !bidResponse.vastXml) { + logWarn('Revantage: Video bid missing VAST content'); + return; + } + } else { + bidResponse.mediaType = BANNER; + bidResponse.ad = rtbBid.adm; + + if (!bidResponse.ad) { + logWarn('Revantage: Banner bid missing ad markup'); + return; + } + } + + // Add DSP price if available + if (rtbBid.ext && rtbBid.ext.dspPrice) { + bidResponse.meta.dspPrice = rtbBid.ext.dspPrice; + } + + bids.push(bidResponse); + }); + } + }); + + return bids; + }, + + getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) { + const syncs = []; + let params = '?cb=' + new Date().getTime(); + + if (gdprConsent) { + if (typeof gdprConsent.gdprApplies === 'boolean') { + params += '&gdpr=' + (gdprConsent.gdprApplies ? 1 : 0); + } + if (typeof gdprConsent.consentString === 'string') { + params += '&gdpr_consent=' + encodeURIComponent(gdprConsent.consentString); + } + } + + if (uspConsent && typeof uspConsent === 'string') { + params += '&us_privacy=' + encodeURIComponent(uspConsent); + } + + if (gppConsent) { + if (gppConsent.gppString) { + params += '&gpp=' + encodeURIComponent(gppConsent.gppString); + } + if (gppConsent.applicableSections) { + params += '&gpp_sid=' + encodeURIComponent(gppConsent.applicableSections.join(',')); + } + } + + if (syncOptions.iframeEnabled) { + syncs.push({ type: 'iframe', url: SYNC_URL + params }); + } + if (syncOptions.pixelEnabled) { + syncs.push({ type: 'image', url: SYNC_URL + params + '&tag=img' }); + } + + return syncs; + }, + + onBidWon: function(bid) { + if (bid.burl) { + triggerPixel(bid.burl); + } + } +}; + +// === MAIN RTB BUILDER === +function makeOpenRtbRequest(validBidRequests, bidderRequest) { + const imp = validBidRequests.map(bid => { + const sizes = getSizes(bid); + const floor = getBidFloorEnhanced(bid); + + const impression = { + id: bid.bidId, + tagid: bid.adUnitCode, + bidfloor: floor, + ext: { + feedId: deepAccess(bid, 'params.feedId'), + bidder: { + placementId: deepAccess(bid, 'params.placementId'), + publisherId: deepAccess(bid, 'params.publisherId') + } + } + }; + + // Add banner specs + if (bid.mediaTypes && bid.mediaTypes.banner) { + impression.banner = { + w: sizes[0][0], + h: sizes[0][1], + format: sizes.map(size => ({ w: size[0], h: size[1] })) + }; + } + + // Add video specs + if (bid.mediaTypes && bid.mediaTypes.video) { + const video = bid.mediaTypes.video; + impression.video = { + mimes: video.mimes || ['video/mp4', 'video/webm'], + minduration: video.minduration || 0, + maxduration: video.maxduration || 60, + protocols: video.protocols || [2, 3, 5, 6], + w: getVideoSize(video.playerSize, 0, 640), + h: getVideoSize(video.playerSize, 1, 360), + placement: video.placement || 1, + playbackmethod: video.playbackmethod || [1, 2], + api: video.api || [1, 2], + skip: video.skip || 0, + skipmin: video.skipmin || 0, + skipafter: video.skipafter || 0, + pos: video.pos || 0, + startdelay: video.startdelay || 0, + linearity: video.linearity || 1 + }; + } + + return impression; + }); + + let user = {}; + if (validBidRequests[0] && validBidRequests[0].userIdAsEids) { + user.eids = deepClone(validBidRequests[0].userIdAsEids); + } + + const ortb2 = bidderRequest.ortb2 || {}; + const site = { + domain: typeof window !== 'undefined' ? window.location.hostname : '', + page: typeof window !== 'undefined' ? window.location.href : '', + ref: typeof document !== 'undefined' ? document.referrer : '' + }; + + // Merge ortb2 site data + if (ortb2.site) { + Object.assign(site, deepClone(ortb2.site)); + } + + const device = deepClone(ortb2.device) || {}; + // Add basic device info if not present + if (!device.ua) { + device.ua = typeof navigator !== 'undefined' ? navigator.userAgent : ''; + } + if (!device.language) { + device.language = typeof navigator !== 'undefined' ? navigator.language : ''; + } + if (!device.w) { + device.w = typeof screen !== 'undefined' ? screen.width : 0; + } + if (!device.h) { + device.h = typeof screen !== 'undefined' ? screen.height : 0; + } + if (!device.devicetype) { + device.devicetype = getDeviceType(); + } + + const regs = { ext: {} }; + if (bidderRequest.gdprConsent) { + regs.ext.gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; + user.ext = { consent: bidderRequest.gdprConsent.consentString }; + } + if (bidderRequest.uspConsent) { + regs.ext.us_privacy = bidderRequest.uspConsent; + } + + // Add GPP consent + if (bidderRequest.gppConsent) { + if (bidderRequest.gppConsent.gppString) { + regs.ext.gpp = bidderRequest.gppConsent.gppString; + } + if (bidderRequest.gppConsent.applicableSections) { + // Send as array, not comma-separated string + regs.ext.gpp_sid = bidderRequest.gppConsent.applicableSections; + } + } + + // Get supply chain + const schain = bidderRequest.schain || (validBidRequests[0] && validBidRequests[0].schain); + + return { + id: bidderRequest.auctionId, + imp: imp, + site: site, + device: device, + user: user, + regs: regs, + schain: schain, + tmax: bidderRequest.timeout || 1000, + cur: ['USD'], + ext: { + prebid: { + version: '$prebid.version$' + } + } + }; +} + +// === UTILS === +function getSizes(bid) { + if (bid.mediaTypes && bid.mediaTypes.banner && Array.isArray(bid.mediaTypes.banner.sizes) && bid.mediaTypes.banner.sizes.length > 0) { + return bid.mediaTypes.banner.sizes; + } + if (bid.mediaTypes && bid.mediaTypes.video && bid.mediaTypes.video.playerSize && bid.mediaTypes.video.playerSize.length > 0) { + return bid.mediaTypes.video.playerSize; + } + if (bid.sizes && bid.sizes.length > 0) { + return bid.sizes; + } + return [[300, 250]]; +} + +function getFirstSize(bid, index, defaultVal) { + const sizes = getSizes(bid); + return (sizes && sizes[0] && sizes[0][index]) || defaultVal; +} + +/** + * Safely extract video dimensions from playerSize. + * Handles both nested [[640, 480]] and flat [640, 480] formats. + * @param {Array} playerSize - video.playerSize from mediaTypes config + * @param {number} index - 0 for width, 1 for height + * @param {number} defaultVal - fallback value + * @returns {number} + */ +function getVideoSize(playerSize, index, defaultVal) { + if (!playerSize || !Array.isArray(playerSize) || playerSize.length === 0) { + return defaultVal; + } + // Nested: [[640, 480]] or [[640, 480], [320, 240]] + if (Array.isArray(playerSize[0])) { + return playerSize[0][index] || defaultVal; + } + // Flat: [640, 480] + if (typeof playerSize[0] === 'number') { + return playerSize[index] || defaultVal; + } + return defaultVal; +} + +/** + * Detect if adm content is VAST XML (for multi-format video detection). + * @param {string} adm - ad markup string + * @returns {boolean} + */ +function isVastAdm(adm) { + if (typeof adm !== 'string') return false; + const trimmed = adm.trim(); + return trimmed.startsWith(' floor && floorInfo.currency === 'USD' && !isNaN(floorInfo.floor)) { + floor = floorInfo.floor; + } + } catch (e) { + // Continue to next size + } + } + + // Fallback to general floor + if (floor === 0) { + try { + const floorInfo = bid.getFloor({ currency: 'USD', mediaType: mediaType, size: '*' }); + if (typeof floorInfo === 'object' && floorInfo.currency === 'USD' && !isNaN(floorInfo.floor)) { + floor = floorInfo.floor; + } + } catch (e) { + logWarn('Revantage: getFloor threw error', e); + } + } + } + return floor; +} + +function getDeviceType() { + if (typeof screen === 'undefined') return 1; + const width = screen.width; + const ua = typeof navigator !== 'undefined' ? navigator.userAgent : ''; + + if (/iPhone|iPod/i.test(ua) || (width < 768 && /Mobile/i.test(ua))) return 2; // Mobile + if (/iPad/i.test(ua) || (width >= 768 && width < 1024)) return 5; // Tablet + return 1; // Desktop/PC +} + +// === REGISTER === +registerBidder(spec); diff --git a/modules/revantageBidAdapter.md b/modules/revantageBidAdapter.md new file mode 100644 index 00000000000..42a4ef4198d --- /dev/null +++ b/modules/revantageBidAdapter.md @@ -0,0 +1,34 @@ +# Overview + +``` +Module Name: ReVantage Bidder Adapter +Module Type: ReVantage Bidder Adapter +Maintainer: bern@revantage.io +``` + +# Description + +Connects to ReVantage exchange for bids. +ReVantage bid adapter supports Banner and Video. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'revantage', + params: { + feedId: 'testfeed', + } + } + ] + } +``` diff --git a/modules/revcontentBidAdapter.js b/modules/revcontentBidAdapter.js index 258f2fc6fb0..81c8a6907bf 100644 --- a/modules/revcontentBidAdapter.js +++ b/modules/revcontentBidAdapter.js @@ -1,12 +1,12 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {_map, deepAccess, isFn, parseGPTSingleSizeArrayToRtbSize, triggerPixel} from '../src/utils.js'; -import {parseDomain} from '../src/refererDetection.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { _map, deepAccess, isFn, parseGPTSingleSizeArrayToRtbSize, triggerPixel } from '../src/utils.js'; +import { parseDomain } from '../src/refererDetection.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; const BIDDER_CODE = 'revcontent'; const GVLID = 203; @@ -56,7 +56,7 @@ export const spec = { } if (typeof domain === 'undefined') { - domain = parseDomain(refererInfo, {noPort: true}); + domain = parseDomain(refererInfo, { noPort: true }); } var endpoint = 'https://' + host + '/rtb?apiKey=' + apiKey + '&userId=' + userId; diff --git a/modules/revnewBidAdapter.ts b/modules/revnewBidAdapter.ts index ecdcdb5e845..c7391b3e485 100644 --- a/modules/revnewBidAdapter.ts +++ b/modules/revnewBidAdapter.ts @@ -1,8 +1,8 @@ import { deepSetValue, generateUUID, logError } from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {AdapterRequest, BidderSpec, registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { getStorageManager } from '../src/storageManager.js'; +import { AdapterRequest, BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { interpretResponse, enrichImp, enrichRequest, getAmxId, getLocalStorageFunctionGenerator, getUserSyncs } from '../libraries/nexx360Utils/index.js'; import { BidRequest, ClientBidderRequest } from '../src/adapterManager.js'; @@ -75,7 +75,7 @@ const buildRequests = ( bidRequests: BidRequest[], bidderRequest: ClientBidderRequest, ): AdapterRequest => { - const data:ORTBRequest = converter.toORTB({bidRequests, bidderRequest}) + const data:ORTBRequest = converter.toORTB({ bidRequests, bidderRequest }) const adapterRequest:AdapterRequest = { method: 'POST', url: REQUEST_URL, diff --git a/modules/rewardedInterestIdSystem.js b/modules/rewardedInterestIdSystem.js index 8cf514f372b..54fa2bb401f 100644 --- a/modules/rewardedInterestIdSystem.js +++ b/modules/rewardedInterestIdSystem.js @@ -28,8 +28,8 @@ * @return {Promise} */ -import {submodule} from '../src/hook.js'; -import {logError} from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { logError } from '../src/utils.js'; export const MODULE_NAME = 'rewardedInterestId'; export const SOURCE = 'rewardedinterest.com'; @@ -103,7 +103,7 @@ export const rewardedInterestIdSubmodule = { * @returns {{rewardedInterestId: string}|undefined} */ decode(value) { - return value ? {[MODULE_NAME]: value} : undefined; + return value ? { [MODULE_NAME]: value } : undefined; }, /** diff --git a/modules/rhythmoneBidAdapter.js b/modules/rhythmoneBidAdapter.js index e3d4b15aebc..ca268a6f949 100644 --- a/modules/rhythmoneBidAdapter.js +++ b/modules/rhythmoneBidAdapter.js @@ -1,8 +1,8 @@ 'use strict'; -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, parseSizesInput, isArray } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; function RhythmOneBidAdapter() { diff --git a/modules/richaudienceBidAdapter.js b/modules/richaudienceBidAdapter.js index cb551bb0b62..5821e8e89c9 100644 --- a/modules/richaudienceBidAdapter.js +++ b/modules/richaudienceBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; +import { deepAccess, triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const BIDDER_CODE = 'richaudience'; @@ -11,7 +11,7 @@ let REFERER = ''; export const spec = { code: BIDDER_CODE, gvlid: 108, - aliases: [{code: 'ra', gvlid: 108}], + aliases: [{ code: 'ra', gvlid: 108 }], supportedMediaTypes: [BANNER, VIDEO], /*** @@ -339,7 +339,7 @@ function raiGetFloor(bid, config) { } function raiGetTimeoutURL(data) { - const {params, timeout} = data[0] + const { params, timeout } = data[0] let url = 'https://s.richaudience.com/err/?ec=6&ev=[timeout_publisher]&pla=[placement_hash]&int=PREBID&pltfm=&node=&dm=[domain]'; url = url.replace('[timeout_publisher]', timeout) diff --git a/modules/riseBidAdapter.js b/modules/riseBidAdapter.js index a6970e959ce..ecd4711a51b 100644 --- a/modules/riseBidAdapter.js +++ b/modules/riseBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {makeBaseSpec} from '../libraries/riseUtils/index.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { makeBaseSpec } from '../libraries/riseUtils/index.js'; import { ALIASES, BASE_URL, diff --git a/modules/rivrAnalyticsAdapter.js b/modules/rivrAnalyticsAdapter.js index 476d3d21337..51772629d5a 100644 --- a/modules/rivrAnalyticsAdapter.js +++ b/modules/rivrAnalyticsAdapter.js @@ -1,12 +1,12 @@ -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import * as utils from '../src/utils.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { getGlobal } from '../src/prebidGlobal.js'; const analyticsType = 'endpoint'; -const rivrAnalytics = Object.assign(adapter({analyticsType}), { +const rivrAnalytics = Object.assign(adapter({ analyticsType }), { track({ eventType, args }) { if (window.rivraddon && window.rivraddon.analytics && window.rivraddon.analytics.getContext() && window.rivraddon.analytics.trackPbjsEvent) { utils.logInfo(`ARGUMENTS FOR TYPE: ============= ${eventType}`, args); @@ -21,7 +21,7 @@ rivrAnalytics.originEnableAnalytics = rivrAnalytics.enableAnalytics; // override enableAnalytics so we can get access to the config passed in from the page rivrAnalytics.enableAnalytics = (config) => { if (window.rivraddon && window.rivraddon.analytics) { - window.rivraddon.analytics.enableAnalytics(config, {utils, ajax, pbjsGlobalVariable: getGlobal()}); + window.rivraddon.analytics.enableAnalytics(config, { utils, ajax, pbjsGlobalVariable: getGlobal() }); rivrAnalytics.originEnableAnalytics(config); } }; diff --git a/modules/robustAppsBidAdapter.js b/modules/robustAppsBidAdapter.js index 8331433d222..4d242e0040c 100644 --- a/modules/robustAppsBidAdapter.js +++ b/modules/robustAppsBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; const BIDDER_CODE = 'robustApps'; const ENDPOINT = 'https://pbjs.rbstsystems.live'; diff --git a/modules/roxotAnalyticsAdapter.js b/modules/roxotAnalyticsAdapter.js index 9cd2bf72b8e..4aca8ef0733 100644 --- a/modules/roxotAnalyticsAdapter.js +++ b/modules/roxotAnalyticsAdapter.js @@ -1,15 +1,15 @@ -import {deepClone, getParameterByName, logError, logInfo} from '../src/utils.js'; +import { deepClone, getParameterByName, logError, logInfo } from '../src/utils.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {ajaxBuilder} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { ajaxBuilder } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'roxot'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); const ajax = ajaxBuilder(0); @@ -310,8 +310,8 @@ function handleOtherEvents(eventType, args) { registerEvent(eventType, eventType, args); } -const roxotAdapter = Object.assign(adapter({url: DEFAULT_EVENT_URL, analyticsType}), { - track({eventType, args}) { +const roxotAdapter = Object.assign(adapter({ url: DEFAULT_EVENT_URL, analyticsType }), { + track({ eventType, args }) { switch (eventType) { case AUCTION_INIT: handleAuctionInit(args); diff --git a/modules/rtbhouseBidAdapter.js b/modules/rtbhouseBidAdapter.js index 9aec645b715..87ba9c0fef8 100644 --- a/modules/rtbhouseBidAdapter.js +++ b/modules/rtbhouseBidAdapter.js @@ -1,9 +1,9 @@ -import {deepAccess, deepClone, isArray, logError, mergeDeep, isEmpty, isPlainObject, isNumber, isStr, deepSetValue} from '../src/utils.js'; -import {getOrigin} from '../libraries/getOrigin/index.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { deepAccess, deepClone, isArray, logError, mergeDeep, isEmpty, isPlainObject, isNumber, isStr, deepSetValue } from '../src/utils.js'; +import { getOrigin } from '../libraries/getOrigin/index.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; -import {convertOrtbRequestToProprietaryNative} from '../src/native.js'; +import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; import { interpretNativeBid, OPENRTB } from '../libraries/precisoUtils/bidNativeUtils.js'; const BIDDER_CODE = 'rtbhouse'; @@ -46,8 +46,8 @@ export const spec = { const consentStr = (bidderRequest.gdprConsent.consentString) ? bidderRequest.gdprConsent.consentString.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '') : ''; const gdpr = bidderRequest.gdprConsent.gdprApplies ? 1 : 0; - request.regs = {ext: {gdpr: gdpr}}; - request.user = {ext: {consent: consentStr}}; + request.regs = { ext: { gdpr: gdpr } }; + request.user = { ext: { consent: consentStr } }; } const bidSchain = validBidRequests[0]?.ortb2?.source?.ext?.schain; if (bidSchain) { @@ -64,7 +64,7 @@ export const spec = { if (request.user && request.user.ext) { request.user.ext = { ...request.user.ext, ...eids }; } else { - request.user = {ext: eids}; + request.user = { ext: eids }; } } @@ -372,7 +372,7 @@ function mapNativeAssets(slot) { * @returns {object} Request Image by OpenRTB Native Ads 1.1 §4.4 */ function mapNativeImage(image, type) { - const img = {type: type}; + const img = { type: type }; if (image.aspect_ratios) { const ratio = image.aspect_ratios[0]; const minWidth = ratio.min_width || 100; diff --git a/modules/rtbsapeBidAdapter.js b/modules/rtbsapeBidAdapter.js index 7db9c574521..803a7a5c6a7 100644 --- a/modules/rtbsapeBidAdapter.js +++ b/modules/rtbsapeBidAdapter.js @@ -1,8 +1,8 @@ import { deepAccess, triggerPixel } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {OUTSTREAM} from '../src/video.js'; -import {Renderer} from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { OUTSTREAM } from '../src/video.js'; +import { Renderer } from '../src/Renderer.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -145,7 +145,7 @@ function setOutstreamRenderer(bid) { props.xml = bid.vastXml; } bid.renderer.push(() => { - const player = window.sapeRtbPlayerHandler(bid.adUnitCode, bid.width, bid.height, bid.playerMuted, {singleton: true}); + const player = window.sapeRtbPlayerHandler(bid.adUnitCode, bid.width, bid.height, bid.playerMuted, { singleton: true }); props.onComplete = () => player.destroy(); props.onError = () => player.destroy(); player.addSlot(props); diff --git a/modules/rtdModule/index.ts b/modules/rtdModule/index.ts index 1b3bff0baf3..fa91f22b467 100644 --- a/modules/rtdModule/index.ts +++ b/modules/rtdModule/index.ts @@ -1,16 +1,16 @@ -import {config} from '../../src/config.js'; -import {getHook, module} from '../../src/hook.js'; -import {logError, logInfo, logWarn, mergeDeep} from '../../src/utils.js'; +import { config } from '../../src/config.js'; +import { getHook, module } from '../../src/hook.js'; +import { logError, logInfo, logWarn, mergeDeep } from '../../src/utils.js'; import * as events from '../../src/events.js'; -import {EVENTS, JSON_MAPPING} from '../../src/constants.js'; -import adapterManager, {gdprDataHandler, gppDataHandler, uspDataHandler} from '../../src/adapterManager.js'; -import {timedAuctionHook} from '../../src/utils/perfMetrics.js'; -import {GDPR_GVLIDS} from '../../src/consentHandler.js'; -import {MODULE_TYPE_RTD} from '../../src/activities/modules.js'; -import {guardOrtb2Fragments} from '../../libraries/objectGuard/ortbGuard.js'; -import {activityParamsBuilder} from '../../src/activities/params.js'; -import type {StartAuctionOptions} from "../../src/prebid.ts"; -import type {ProviderConfig, RTDProvider, RTDProviderConfig} from "./spec.ts"; +import { EVENTS, JSON_MAPPING } from '../../src/constants.js'; +import adapterManager, { gdprDataHandler, gppDataHandler, uspDataHandler } from '../../src/adapterManager.js'; +import { timedAuctionHook } from '../../src/utils/perfMetrics.js'; +import { GDPR_GVLIDS } from '../../src/consentHandler.js'; +import { MODULE_TYPE_RTD } from '../../src/activities/modules.js'; +import { guardOrtb2Fragments } from '../../libraries/objectGuard/ortbGuard.js'; +import { activityParamsBuilder } from '../../src/activities/params.js'; +import type { StartAuctionOptions } from "../../src/prebid.ts"; +import type { ProviderConfig, RTDProvider, RTDProviderConfig } from "./spec.ts"; const activityParams = activityParamsBuilder((al) => adapterManager.resolveAlias(al)); @@ -87,7 +87,7 @@ declare module '../../src/config' { } export function init(config) { - const confListener = config.getConfig(MODULE_NAME, ({realTimeData}) => { + const confListener = config.getConfig(MODULE_NAME, ({ realTimeData }) => { if (!realTimeData.dataProviders) { logError('missing parameters for real time module'); return; @@ -122,7 +122,7 @@ function initSubModules() { const sm = ((registeredSubModules) || []).find(s => s.name === provider.name); const initResponse = sm && sm.init && sm.init(provider, _userConsent); if (initResponse) { - subModulesByOrder.push(Object.assign(sm, {config: provider})); + subModulesByOrder.push(Object.assign(sm, { config: provider })); } }); subModules = subModulesByOrder; diff --git a/modules/rtdModule/spec.ts b/modules/rtdModule/spec.ts index 7abf38e1247..60276400c1d 100644 --- a/modules/rtdModule/spec.ts +++ b/modules/rtdModule/spec.ts @@ -1,9 +1,9 @@ -import type {AllConsentData} from "../../src/consentHandler.ts"; -import type {AdUnitCode, ByAdUnit, StorageDisclosure} from "../../src/types/common"; -import {EVENTS} from '../../src/constants.ts'; -import type {EventPayload} from "../../src/events.ts"; -import type {TargetingMap} from "../../src/targeting.ts"; -import type {StartAuctionOptions} from "../../src/prebid.ts"; +import type { AllConsentData } from "../../src/consentHandler.ts"; +import type { AdUnitCode, ByAdUnit, StorageDisclosure } from "../../src/types/common"; +import { EVENTS } from '../../src/constants.ts'; +import type { EventPayload } from "../../src/events.ts"; +import type { TargetingMap } from "../../src/targeting.ts"; +import type { StartAuctionOptions } from "../../src/prebid.ts"; export type RTDProvider = string; diff --git a/modules/rubiconBidAdapter.js b/modules/rubiconBidAdapter.js index a3c05dabe5d..737295172a9 100644 --- a/modules/rubiconBidAdapter.js +++ b/modules/rubiconBidAdapter.js @@ -21,8 +21,8 @@ import { _each, isPlainObject } from '../src/utils.js'; -import {getAllOrtbKeywords} from '../libraries/keywords/keywords.js'; -import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js'; +import { getAllOrtbKeywords } from '../libraries/keywords/keywords.js'; +import { getUserSyncParams } from '../libraries/userSyncUtils/userSyncUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -30,7 +30,7 @@ import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js'; const DEFAULT_INTEGRATION = 'pbjs_lite'; const DEFAULT_PBS_INTEGRATION = 'pbjs'; -const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.2.1.js'; +const DEFAULT_RENDERER_URL = 'https://video-outstream.rubiconproject.com/apex-2.3.7.js'; // renderer code at https://github.com/rubicon-project/apex2 let rubiConf = config.getConfig('rubicon') || {}; @@ -116,6 +116,7 @@ var sizeMap = { 210: '1080x1920', 213: '1030x590', 214: '980x360', + 219: '1920x1080', 221: '1x1', 229: '320x180', 230: '2000x1400', @@ -128,7 +129,6 @@ var sizeMap = { 259: '998x200', 261: '480x480', 264: '970x1000', - 265: '1920x1080', 274: '1800x200', 278: '320x500', 282: '320x400', @@ -168,7 +168,7 @@ _each(sizeMap, (item, key) => { export const converter = ortbConverter({ request(buildRequest, imps, bidderRequest, context) { - const {bidRequests} = context; + const { bidRequests } = context; const data = buildRequest(imps, bidderRequest, context); data.cur = ['USD']; data.test = config.getConfig('debug') ? 1 : 0; @@ -188,7 +188,7 @@ export const converter = ortbConverter({ const modules = (getGlobal()).installedModules; if (modules && (!modules.length || modules.indexOf('rubiconAnalyticsAdapter') !== -1)) { - deepSetValue(data, 'ext.prebid.analytics', {'rubicon': {'client-analytics': true}}); + deepSetValue(data, 'ext.prebid.analytics', { 'rubicon': { 'client-analytics': true } }); } addOrtbFirstPartyData(data, bidRequests, bidderRequest.ortb2); @@ -233,7 +233,7 @@ export const converter = ortbConverter({ bidResponse(buildBidResponse, bid, context) { const bidResponse = buildBidResponse(bid, context); bidResponse.meta.mediaType = deepAccess(bid, 'ext.prebid.type'); - const {bidRequest} = context; + const { bidRequest } = context; const [parseSizeWidth, parseSizeHeight] = bidRequest.mediaTypes.video?.context === 'outstream' ? parseSizes(bidRequest, VIDEO) : [undefined, undefined]; // 0 by default to avoid undefined size @@ -317,7 +317,7 @@ export const spec = { }); if (filteredRequests && filteredRequests.length) { - const data = converter.toORTB({bidRequests: filteredRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests: filteredRequests, bidderRequest }); resetImpIdMap(); filteredHttpRequest.push({ @@ -330,7 +330,7 @@ export const spec = { const bannerBidRequests = bidRequests.filter((req) => { const mediaTypes = bidType(req) || []; - const {bidonmultiformat, video} = req.params || {}; + const { bidonmultiformat, video } = req.params || {}; return ( // Send to fastlane if: it must include BANNER and... mediaTypes.includes(BANNER) && ( @@ -535,7 +535,7 @@ export const spec = { // add p_pos only if specified and valid // For SRA we need to explicitly put empty semi colons so AE treats it as empty, instead of copying the latter value - const posMapping = {1: 'atf', 3: 'btf'}; + const posMapping = { 1: 'atf', 3: 'btf' }; const pos = posMapping[deepAccess(bidRequest, 'mediaTypes.banner.pos')] || ''; data['p_pos'] = (params.position === 'atf' || params.position === 'btf') ? params.position : pos; @@ -655,7 +655,7 @@ export const spec = { */ interpretResponse: function (responseObj, request) { responseObj = responseObj.body; - const {data} = request; + const { data } = request; // check overall response if (!responseObj || typeof responseObj !== 'object') { @@ -667,14 +667,14 @@ export const spec = { if (Array.isArray(responseErrors) && responseErrors.length > 0) { logWarn('Rubicon: Error in video response'); } - const bids = converter.fromORTB({request: data, response: responseObj}).bids; + const bids = converter.fromORTB({ request: data, response: responseObj }).bids; return bids; } let ads = responseObj.ads; let lastImpId; let multibid = 0; - const {bidRequest} = request; + const { bidRequest } = request; // video ads array is wrapped in an object if (typeof bidRequest === 'object' && !Array.isArray(bidRequest) && bidType(bidRequest).includes(VIDEO) && typeof ads === 'object') { @@ -752,7 +752,7 @@ export const spec = { .reduce((memo, item) => { memo[item.key] = item.values[0]; return memo; - }, {'rpfl_elemid': associatedBidRequest.adUnitCode}); + }, { 'rpfl_elemid': associatedBidRequest.adUnitCode }); bids.push(bid); } else { @@ -909,8 +909,8 @@ function parseSizes(bid, mediaType) { function applyFPD(bidRequest, mediaType, data) { const BID_FPD = { - user: {ext: {data: {...bidRequest.params.visitor}}}, - site: {ext: {data: {...bidRequest.params.inventory}}} + user: { ext: { data: { ...bidRequest.params.visitor } } }, + site: { ext: { data: { ...bidRequest.params.inventory } } } }; if (bidRequest.params.keywords) BID_FPD.site.keywords = (isArray(bidRequest.params.keywords)) ? bidRequest.params.keywords.join(',') : bidRequest.params.keywords; @@ -921,8 +921,8 @@ function applyFPD(bidRequest, mediaType, data) { const gpid = deepAccess(bidRequest, 'ortb2Imp.ext.gpid'); const dsa = deepAccess(fpd, 'regs.ext.dsa'); - const SEGTAX = {user: [4], site: [1, 2, 5, 6, 7]}; - const MAP = {user: 'tg_v.', site: 'tg_i.', adserver: 'tg_i.dfp_ad_unit_code', pbadslot: 'tg_i.pbadslot', keywords: 'kw'}; + const SEGTAX = { user: [4], site: [1, 2, 5, 6, 7] }; + const MAP = { user: 'tg_v.', site: 'tg_i.', adserver: 'tg_i.dfp_ad_unit_code', pbadslot: 'tg_i.pbadslot', keywords: 'kw' }; const validate = function(prop, key, parentName) { if (key === 'data' && Array.isArray(prop)) { return prop.filter(name => name.segment && deepAccess(name, 'ext.segtax') && SEGTAX[parentName] && @@ -1204,18 +1204,18 @@ export function determineRubiconVideoSizeId(bid) { export function getPriceGranularity(config) { return { ranges: { - low: [{max: 5.00, increment: 0.50}], - medium: [{max: 20.00, increment: 0.10}], - high: [{max: 20.00, increment: 0.01}], + low: [{ max: 5.00, increment: 0.50 }], + medium: [{ max: 20.00, increment: 0.10 }], + high: [{ max: 20.00, increment: 0.01 }], auto: [ - {max: 5.00, increment: 0.05}, - {min: 5.00, max: 10.00, increment: 0.10}, - {min: 10.00, max: 20.00, increment: 0.50} + { max: 5.00, increment: 0.05 }, + { min: 5.00, max: 10.00, increment: 0.10 }, + { min: 10.00, max: 20.00, increment: 0.50 } ], dense: [ - {max: 3.00, increment: 0.01}, - {min: 3.00, max: 8.00, increment: 0.05}, - {min: 8.00, max: 20.00, increment: 0.50} + { max: 3.00, increment: 0.01 }, + { min: 3.00, max: 8.00, increment: 0.05 }, + { min: 8.00, max: 20.00, increment: 0.50 } ], custom: config.getConfig('customPriceBucket') && config.getConfig('customPriceBucket').buckets }[config.getConfig('priceGranularity')] @@ -1313,8 +1313,8 @@ function addOrtbFirstPartyData(data, nonBannerRequests, ortb2) { const keywords = getAllOrtbKeywords(ortb2, ...nonBannerRequests.map(req => req.params.keywords)) nonBannerRequests.forEach(bidRequest => { const bidFirstPartyData = { - user: {ext: {data: {...bidRequest.params.visitor}}}, - site: {ext: {data: {...bidRequest.params.inventory}}} + user: { ext: { data: { ...bidRequest.params.visitor } } }, + site: { ext: { data: { ...bidRequest.params.inventory } } } }; // add site.content.language diff --git a/modules/rules/index.ts b/modules/rules/index.ts new file mode 100644 index 00000000000..d9dccd6a86b --- /dev/null +++ b/modules/rules/index.ts @@ -0,0 +1,506 @@ +import { setLabels } from "../../libraries/analyticsAdapter/AnalyticsAdapter.ts"; +import { timeoutQueue } from "../../libraries/timeoutQueue/timeoutQueue.ts"; +import { ACTIVITY_ADD_BID_RESPONSE, ACTIVITY_FETCH_BIDS } from "../../src/activities/activities.js"; +import { MODULE_TYPE_BIDDER } from "../../src/activities/modules.ts"; +import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE } from "../../src/activities/params.js"; +import { registerActivityControl } from "../../src/activities/rules.js"; +import { ajax } from "../../src/ajax.ts"; +import { AuctionIndex } from "../../src/auctionIndex.js"; +import { auctionManager } from "../../src/auctionManager.js"; +import { config } from "../../src/config.ts"; +import { getHook } from "../../src/hook.ts"; +import { generateUUID, logInfo, logWarn } from "../../src/utils.ts"; +import { timedAuctionHook } from "../../src/utils/perfMetrics.ts"; + +/** + * Configuration interface for the shaping rules module. + */ +interface ShapingRulesConfig { + /** + * Endpoint configuration for fetching rules from a remote server. + * If not provided, rules must be provided statically via the `rules` property. + */ + endpoint?: { + /** URL endpoint to fetch rules configuration from */ + url: string; + /** HTTP method to use for fetching rules (currently only 'GET' is supported) */ + method: string; + }; + /** + * Static rules configuration object. + * If provided, rules will be used directly without fetching from endpoint. + * Takes precedence over endpoint configuration. + */ + rules?: RulesConfig; + /** + * Delay in milliseconds to wait for rules to be fetched before starting the auction. + * If rules are not loaded within this delay, the auction will proceed anyway. + * Default: 0 (no delay) + */ + auctionDelay?: number; + /** + * Custom schema evaluator functions to extend the default set of evaluators. + * Keys are function names, values are evaluator functions that take args and context, + * and return a function that evaluates to a value when called. + */ + extraSchemaEvaluators?: { + [key: string]: (args: any[], context: any) => () => any; + }; +} + +/** + * Schema function definition used to compute values. + */ +interface ModelGroupSchema { + /** Function name inside the schema */ + function: string; + /** Arguments for the schema function */ + args?: any[]; +} + +/** + * Model group configuration for A/B testing with different rule configurations. + * Only one object within the group is chosen based on weight. + */ +interface ModelGroup { + /** Determines selection probability; only one object within the group is chosen */ + weight: number; + /** Indicates whether this model group is selected (set automatically based on weight) */ + selected?: boolean; + /** Optional key used to produce aTags, identifying experiments or optimization targets */ + analyticsKey: string; + /** Version identifier for analytics */ + version: string; + /** + * Optional array of functions used to compute values. + * Without it, only the default rule is applied. + */ + schema: ModelGroupSchema[]; + /** + * Optional rule array; if absent, only the default rule is used. + * Each rule has conditions that must be met and results that are triggered. + */ + rules: [{ + /** Conditions that must be met for the rule to apply */ + conditions: string[]; + /** Resulting actions triggered when conditions are met */ + results: [ + { + /** Function defining the result action */ + function: string; + /** Arguments for the result function */ + args: any[]; + } + ]; + }]; + /** + * Default results object used if errors occur or when no schema or rules are defined. + * Exists outside the rules array for structural clarity. + */ + default?: Array<{ + /** Function defining the default result action */ + function: string; + /** Arguments for the default result function */ + args: any; + }>; +} + +/** + * Independent set of rules that can be applied to a specific stage of the auction. + */ +interface RuleSet { + /** Human-readable name of the ruleset */ + name: string; + /** + * Indicates which module stage the ruleset applies to. + * Can be either `processed-auction-request` or `processed-auction` + */ + stage: string; + /** Version identifier for the ruleset */ + version: string; + /** + * Optional timestamp of the last update (ISO 8601 format: `YYYY-MM-DDThh:mm:ss[.sss][Z or ±hh:mm]`) + */ + timestamp?: string; + /** + * One or more model groups for A/B testing with different rule configurations. + * Allows A/B testing with different rule configurations. + */ + modelGroups: ModelGroup[]; +} + +/** + * Main configuration object for the shaping rules module. + */ +interface RulesConfig { + /** Version identifier for the rules configuration */ + version: string; + /** One or more independent sets of rules */ + ruleSets: RuleSet[]; + /** Optional timestamp of the last update (ISO 8601 format: `YYYY-MM-DDThh:mm:ss[.sss][Z or ±hh:mm]`) */ + timestamp?: string; + /** Enables or disables the module. Default: `true` */ + enabled: boolean; +} + +declare module '../../src/config' { + interface Config { + shapingRules?: ShapingRulesConfig; + } +} + +const MODULE_NAME = 'shapingRules'; + +const globalRandomStore = new WeakMap<{ auctionId: string }, number>(); + +let auctionConfigStore = new Map(); + +export const dep = { + getGlobalRandom: getGlobalRandom +}; + +function getGlobalRandom(auctionId: string, auctionIndex: AuctionIndex = auctionManager.index) { + if (!auctionId) { + return Math.random(); + } + const auction = auctionIndex.getAuction({ auctionId }); + if (!globalRandomStore.has(auction)) { + globalRandomStore.set(auction, Math.random()); + } + return globalRandomStore.get(auction); +} + +const unregisterFunctions: Array<() => void> = [] + +let moduleConfig: ShapingRulesConfig = { + endpoint: { + method: 'GET', + url: '' + }, + auctionDelay: 0, + extraSchemaEvaluators: {} +}; + +let fetching = false; + +let rulesLoaded = false; + +const delayedAuctions = timeoutQueue(); + +let rulesConfig: RulesConfig = null; + +export function evaluateConfig(config: RulesConfig, auctionId: string) { + if (!config || !config.ruleSets) { + logWarn(`${MODULE_NAME}: Invalid structure for rules engine`); + return; + } + + if (!config.enabled) { + logInfo(`${MODULE_NAME}: Rules engine is disabled in the configuration.`); + return; + } + + const stageRules = config.ruleSets; + + const modelGroupsWithStage = getAssignedModelGroups(stageRules || []); + + for (const { modelGroups, stage } of modelGroupsWithStage) { + const modelGroup = modelGroups.find(group => group.selected); + if (!modelGroup) continue; + evaluateRules(modelGroup.rules || [], modelGroup.schema || [], stage, modelGroup.analyticsKey, auctionId, modelGroup.default); + } +} + +export function getAssignedModelGroups(rulesets: RuleSet[]): Array<{ modelGroups: ModelGroup[], stage: string }> { + return rulesets.flatMap(ruleset => { + const { modelGroups, stage } = ruleset; + if (!modelGroups?.length) { + return []; + } + + // Calculate cumulative weights for proper weighted random selection + let cumulativeWeight = 0; + const groupsWithCumulativeWeights = modelGroups.map(group => { + const groupWeight = group.weight ?? 100; + cumulativeWeight += groupWeight; + return { + group, + cumulativeWeight + }; + }); + + const weightSum = cumulativeWeight; + // Generate random value in range [0, weightSum) + // This ensures each group gets probability proportional to its weight + const randomValue = Math.random() * weightSum; + + // Find first group where cumulative weight >= randomValue + let selectedIndex = groupsWithCumulativeWeights.findIndex(({ cumulativeWeight }) => randomValue < cumulativeWeight); + + // Fallback: if no group was selected (shouldn't happen, but safety check) + if (selectedIndex === -1) { + selectedIndex = modelGroups.length - 1; + } + + // Create new model groups array with selected flag + const newModelGroups = modelGroups.map((group, index) => ({ + ...group, + selected: index === selectedIndex + })); + + return { + modelGroups: newModelGroups, + stage + }; + }); +} + +function evaluateRules(rules, schema, stage, analyticsKey, auctionId: string, defaultResults?) { + const modelGroupConfig = auctionConfigStore.get(auctionId) || []; + modelGroupConfig.push({ + rules, + schema, + stage, + analyticsKey, + defaultResults, + }); + auctionConfigStore.set(auctionId, modelGroupConfig); +} + +const schemaEvaluators = { + percent: (args, context) => () => { + const auctionId = context.auctiondId || context.bid?.auctionId; + return dep.getGlobalRandom(auctionId) * 100 < args[0] + }, + adUnitCode: (args, context) => () => context.adUnit.code, + adUnitCodeIn: (args, context) => () => args[0].includes(context.adUnit.code), + deviceCountry: (args, context) => () => context.ortb2?.device?.geo?.country, + deviceCountryIn: (args, context) => () => args[0].includes(context.ortb2?.device?.geo?.country), + channel: (args, context) => () => 'web', + eidAvailable: (args, context) => () => { + const eids = context.ortb2?.user?.eids || []; + return eids.length > 0; + }, + userFpdAvailable: (args, context) => () => { + const fpd = context.ortb2?.user?.data || {}; + const extFpd = context.ortb2?.user?.ext?.data || {}; + const mergedFpd = { ...fpd, ...extFpd }; + return Object.keys(mergedFpd).length > 0; + }, + fpdAvailable: (args, context) => () => { + const extData = context.ortb2?.user?.ext?.data || {}; + const usrData = context.ortb2?.user?.data || {}; + const siteExtData = context.ortb2?.site?.ext?.data || {}; + const siteContentData = context.ortb2?.site?.content?.data || {}; + const appExtData = context.ortb2?.app?.ext?.data || {}; + const appContentData = context.ortb2?.app?.content?.data || {}; + const mergedFpd = { ...extData, ...usrData, ...siteExtData, ...siteContentData, ...appExtData, ...appContentData }; + return Object.keys(mergedFpd).length > 0; + }, + gppSidIn: (args, context) => () => { + const gppSids = context.ortb2?.regs?.gpp_sid || []; + return args[0].some((sid) => gppSids.includes(sid)); + }, + tcfInScope: (args, context) => () => context.ortb2?.regs?.ext?.gdpr === 1, + domain: (args, context) => () => { + const domain = context.ortb2?.site?.domain || context.ortb2?.app?.domain || ''; + return domain; + }, + domainIn: (args, context) => () => { + const domain = context.ortb2?.site?.domain || context.ortb2?.app?.domain || ''; + return args[0].includes(domain); + }, + bundle: (args, context) => () => { + const bundle = context.ortb2?.app?.bundle || ''; + return bundle; + }, + bundleIn: (args, context) => () => { + const bundle = context.ortb2?.app?.bundle || ''; + return args[0].includes(bundle); + }, + mediaTypeIn: (args, context) => () => { + const mediaTypes = Object.keys(context.adUnit?.mediaTypes) || []; + return args[0].some((type) => mediaTypes.includes(type)); + }, + deviceTypeIn: (args, context) => () => { + const deviceType = context.ortb2?.device?.devicetype; + return args[0].includes(deviceType); + }, + bidPrice: (args, context) => () => { + const [operator, currency, value] = args || []; + const { cpm: bidPrice, currency: bidCurrency } = context.bid || {}; + if (bidCurrency !== currency) { + return false; + } + if (operator === 'gt') { + return bidPrice > value; + } else if (operator === 'gte') { + return bidPrice >= value; + } else if (operator === 'lt') { + return bidPrice < value; + } else if (operator === 'lte') { + return bidPrice <= value; + } + return false; + } +}; + +export function evaluateSchema(func, args, context) { + const extraEvaluators = moduleConfig.extraSchemaEvaluators || {}; + const evaluators = { ...schemaEvaluators, ...extraEvaluators }; + const evaluator = evaluators[func]; + if (evaluator) { + return evaluator(args, context); + } + return () => null; +} + +function evaluateCondition(condition, func) { + switch (condition) { + case '*': + return true + case 'true': + return func() === true; + case 'false': + return func() === false; + default: + return func() === condition; + } +} + +export function fetchRules(endpoint = moduleConfig.endpoint) { + if (fetching) { + logWarn(`${MODULE_NAME}: A fetch is already occurring. Skipping.`); + return; + } + + if (!endpoint?.url || endpoint?.method !== 'GET') return; + + fetching = true; + ajax(endpoint.url, { + success: (response: any) => { + fetching = false; + rulesLoaded = true; + rulesConfig = JSON.parse(response); + delayedAuctions.resume(); + logInfo(`${MODULE_NAME}: Rules configuration fetched successfully.`); + }, + error: () => { + fetching = false; + } + }, null, { method: 'GET' }); +} + +export function registerActivities() { + const stages = { + [ACTIVITY_FETCH_BIDS]: 'processed-auction-request', + [ACTIVITY_ADD_BID_RESPONSE]: 'processed-auction', + }; + + [ACTIVITY_FETCH_BIDS, ACTIVITY_ADD_BID_RESPONSE].forEach(activity => { + unregisterFunctions.push( + registerActivityControl(activity, MODULE_NAME, (params) => { + const auctionId = params.auctionId || params.bid?.auctionId; + if (params[ACTIVITY_PARAM_COMPONENT_TYPE] !== MODULE_TYPE_BIDDER) return; + if (!auctionId) return; + + const checkConditions = ({ schema, conditions, stage }) => { + for (const [index, schemaEntry] of schema.entries()) { + const schemaFunction = evaluateSchema(schemaEntry.function, schemaEntry.args || [], params); + if (evaluateCondition(conditions[index], schemaFunction)) { + return true; + } + } + return false; + } + + const results = []; + let modelGroups = auctionConfigStore.get(auctionId) || []; + modelGroups = modelGroups.filter(modelGroup => modelGroup.stage === stages[activity]); + + // evaluate applicable results for each model group + for (const modelGroup of modelGroups) { + // find first rule that matches conditions + const selectedRule = modelGroup.rules.find(rule => checkConditions({ ...rule, schema: modelGroup.schema })); + if (selectedRule) { + results.push(...selectedRule.results); + } else if (Array.isArray(modelGroup.defaultResults)) { + const defaults = modelGroup.defaultResults.map(result => ({ ...result, analyticsKey: modelGroup.analyticsKey })); + results.push(...defaults); + } + } + + // set analytics labels for logAtag results + results + .filter(result => result.function === 'logAtag') + .forEach((result) => { + setLabels({ [auctionId + '-' + result.analyticsKey]: result.args.analyticsValue }); + }); + + // verify current bidder against applicable rules + const allow = results + .filter(result => ['excludeBidders', 'includeBidders'].includes(result.function)) + .every((result) => { + return result.args.every(({ bidders }) => { + const bidderIncluded = bidders.includes(params[ACTIVITY_PARAM_COMPONENT_NAME]); + return result.function === 'excludeBidders' ? !bidderIncluded : bidderIncluded; + }); + }); + + if (!allow) { + return { allow, reason: `Bidder ${params.bid?.bidder} excluded by rules module` }; + } + }) + ); + }); +} + +export const startAuctionHook = timedAuctionHook('rules', function startAuctionHook(fn, req) { + req.auctionId = req.auctionId || generateUUID(); + evaluateConfig(rulesConfig, req.auctionId); + fn.call(this, req); +}); + +export const requestBidsHook = timedAuctionHook('rules', function requestBidsHook(fn, reqBidsConfigObj) { + const { auctionDelay = 0 } = moduleConfig; + const continueAuction = ((that) => () => fn.call(that, reqBidsConfigObj))(this); + + if (!rulesLoaded && auctionDelay > 0) { + delayedAuctions.submit(auctionDelay, continueAuction, () => { + logWarn(`${MODULE_NAME}: Fetch attempt did not return in time for auction ${reqBidsConfigObj.auctionId}`) + continueAuction(); + }); + } else { + continueAuction(); + } +}); + +function init(config: ShapingRulesConfig) { + moduleConfig = config; + registerActivities(); + auctionManager.onExpiry(auction => { + auctionConfigStore.delete(auction.getAuctionId()); + }); + // use static config if provided + if (config.rules) { + rulesConfig = config.rules; + } else { + fetchRules(); + } + getHook('requestBids').before(requestBidsHook, 50); + getHook('startAuction').before(startAuctionHook, 50); +} + +export function reset() { + try { + getHook('requestBids').getHooks({ hook: requestBidsHook }).remove(); + getHook('startAuction').getHooks({ hook: startAuctionHook }).remove(); + unregisterFunctions.forEach(unregister => unregister()); + unregisterFunctions.length = 0; + auctionConfigStore.clear(); + } catch (e) { + } + setLabels({}); +} + +config.getConfig(MODULE_NAME, config => init(config[MODULE_NAME])); diff --git a/modules/rumbleBidAdapter.js b/modules/rumbleBidAdapter.js index b4be549d394..0f5317d5511 100644 --- a/modules/rumbleBidAdapter.js +++ b/modules/rumbleBidAdapter.js @@ -106,13 +106,13 @@ export const spec = { return { url: endpoint, method: 'POST', - data: converter.toORTB({bidRequests: [bid], bidderRequest}), + data: converter.toORTB({ bidRequests: [bid], bidderRequest }), bidRequest: bid, }; }) }, interpretResponse(response, request) { - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; }, onBidWon: function(bid) { if (bid.burl) { diff --git a/modules/s2sTesting.js b/modules/s2sTesting.js index 18079118ffa..8f7b2b70dd7 100644 --- a/modules/s2sTesting.js +++ b/modules/s2sTesting.js @@ -1,7 +1,7 @@ -import {PARTITIONS, partitionBidders, filterBidsForAdUnit, getS2SBidderSet} from '../src/adapterManager.js'; -import {getBidderCodes, logWarn} from '../src/utils.js'; +import { PARTITIONS, partitionBidders, filterBidsForAdUnit, getS2SBidderSet } from '../src/adapterManager.js'; +import { getBidderCodes, logWarn } from '../src/utils.js'; -const {CLIENT, SERVER} = PARTITIONS; +const { CLIENT, SERVER } = PARTITIONS; export const s2sTesting = { ...PARTITIONS, clientTestBidders: new Set() @@ -11,7 +11,7 @@ s2sTesting.bidSource = {}; // store bidder sources determined from s2sConfig bid s2sTesting.globalRand = Math.random(); // if 10% of bidderA and 10% of bidderB should be server-side, make it the same 10% s2sTesting.getSourceBidderMap = function(adUnits = [], allS2SBidders = []) { - var sourceBidders = {[SERVER]: {}, [CLIENT]: {}}; + var sourceBidders = { [SERVER]: {}, [CLIENT]: {} }; adUnits.forEach((adUnit) => { // if any adUnit bidders specify a bidSource, include them @@ -117,7 +117,7 @@ partitionBidders.before(function (next, adUnits, s2sConfigs) { memo[CLIENT].push(bidder); } return memo; - }, {[CLIENT]: [], [SERVER]: []})); + }, { [CLIENT]: [], [SERVER]: [] })); }); filterBidsForAdUnit.before(function(next, bids, s2sConfig) { diff --git a/modules/scaleableAnalyticsAdapter.js b/modules/scaleableAnalyticsAdapter.js index cb2fc34737a..dda050f660f 100644 --- a/modules/scaleableAnalyticsAdapter.js +++ b/modules/scaleableAnalyticsAdapter.js @@ -74,7 +74,7 @@ const sendDataToServer = data => ajax(URL, () => {}, JSON.stringify(data)); // Track auction initiated const onAuctionInit = args => { - const config = scaleableAnalytics.config || {options: {}}; + const config = scaleableAnalytics.config || { options: {} }; const adunitObj = {}; const adunits = []; @@ -114,7 +114,7 @@ const onAuctionInit = args => { // Handle all events besides requests and wins const onAuctionEnd = args => { - const config = scaleableAnalytics.config || {options: {}}; + const config = scaleableAnalytics.config || { options: {} }; const adunitObj = {}; const adunits = []; @@ -167,7 +167,7 @@ const onAuctionEnd = args => { // Bid Win Events occur after auction end const onBidWon = args => { - const config = scaleableAnalytics.config || {options: {}}; + const config = scaleableAnalytics.config || { options: {} }; const data = { event: 'win', diff --git a/modules/scaliburBidAdapter.js b/modules/scaliburBidAdapter.js index b8b05c3ac61..fcea9317881 100644 --- a/modules/scaliburBidAdapter.js +++ b/modules/scaliburBidAdapter.js @@ -1,8 +1,8 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {sizesToSizeTuples} from "../src/utils.js"; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { sizesToSizeTuples } from "../src/utils.js"; const BIDDER_CODE = 'scalibur'; const ENDPOINT_SERVER = new URLSearchParams(window.location.search).get('sclServer') || 'srv'; @@ -14,7 +14,7 @@ const BIDDER_VERSION = '1.0.0'; const IFRAME_TYPE_Q_PARAM = 'iframe'; const IMAGE_TYPE_Q_PARAM = 'img'; const GVLID = 1471; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const STORAGE_KEY = `${BIDDER_CODE}_fp_data`; export const spec = { @@ -92,7 +92,7 @@ export const spec = { } // Floor Price - const floor = bid.getFloor ? bid.getFloor({currency: DEFAULT_CURRENCY, mediaType: '*', size: '*'}) : {}; + const floor = bid.getFloor ? bid.getFloor({ currency: DEFAULT_CURRENCY, mediaType: '*', size: '*' }) : {}; imp.bidfloor = floor.floor || bid.params.bidfloor || 0; imp.bidfloorcur = floor.currency || bid.params.bidfloorcur || DEFAULT_CURRENCY; @@ -212,10 +212,10 @@ export const spec = { const syncs = []; if (syncOptions.iframeEnabled) { - syncs.push({type: 'iframe', url: `${SYNC_IFRAME_URL}?${queryParams}`}); + syncs.push({ type: 'iframe', url: `${SYNC_IFRAME_URL}?${queryParams}` }); } if (syncOptions.pixelEnabled) { - syncs.push({type: 'image', url: `${SYNC_PIXEL_URL}?${queryParams}`}); + syncs.push({ type: 'image', url: `${SYNC_PIXEL_URL}?${queryParams}` }); } return syncs; }, diff --git a/modules/schain.ts b/modules/schain.ts index 6b864e4d70a..941115b9e23 100644 --- a/modules/schain.ts +++ b/modules/schain.ts @@ -1,7 +1,7 @@ -import {config} from '../src/config.js'; -import {deepClone, logWarn} from '../src/utils.js'; -import {normalizeFPD} from '../src/fpd/normalize.js'; -import type {ORTBRequest} from "../src/types/ortb/request"; +import { config } from '../src/config.js'; +import { deepClone, logWarn } from '../src/utils.js'; +import { normalizeFPD } from '../src/fpd/normalize.js'; +import type { ORTBRequest } from "../src/types/ortb/request"; export type SchainConfig = { config: ORTBRequest['source']['schain']; diff --git a/modules/screencoreBidAdapter.js b/modules/screencoreBidAdapter.js index ccf59b28ce7..e7c38c66a3a 100644 --- a/modules/screencoreBidAdapter.js +++ b/modules/screencoreBidAdapter.js @@ -25,7 +25,8 @@ const REGION_SUBDOMAIN_SUFFIX = { */ function getRegionSubdomainSuffix() { try { - const region = getTimeZone().split('/')[0]; + const tz = getTimeZone(); + const region = tz.split('/')[0]; switch (region) { case 'Asia': @@ -40,6 +41,8 @@ function getRegionSubdomainSuffix() { case 'Arctic': return REGION_SUBDOMAIN_SUFFIX['EU']; case 'America': + case 'US': + case 'Canada': return REGION_SUBDOMAIN_SUFFIX['US']; default: return REGION_SUBDOMAIN_SUFFIX['EU']; @@ -55,11 +58,10 @@ export function createDomain() { return `https://${subDomain}.screencore.io`; } -const AD_URL = `${createDomain()}/prebid`; - const placementProcessingFunction = buildPlacementProcessingFunction(); const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + const AD_URL = `${createDomain()}/pbjs`; return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); }; diff --git a/modules/seedingAllianceBidAdapter.js b/modules/seedingAllianceBidAdapter.js index b22641cfb39..6a738e07299 100755 --- a/modules/seedingAllianceBidAdapter.js +++ b/modules/seedingAllianceBidAdapter.js @@ -1,12 +1,12 @@ // jshint esversion: 6, es3: false, node: true 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE} from '../src/mediaTypes.js'; -import {generateUUID, deepSetValue, isEmpty, replaceAuctionPrice} from '../src/utils.js'; -import {config} from '../src/config.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { generateUUID, deepSetValue, isEmpty, replaceAuctionPrice } from '../src/utils.js'; +import { config } from '../src/config.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; const GVL_ID = 371; const BIDDER_CODE = 'seedingAlliance'; @@ -14,7 +14,7 @@ const DEFAULT_CUR = 'EUR'; const ENDPOINT_URL = 'https://b.nativendo.de/cds/rtb/bid?format=openrtb2.5&ssp=pb'; const NATIVENDO_KEY = 'nativendo_id'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const converter = ortbConverter({ context: { @@ -52,7 +52,7 @@ export const spec = { }, buildRequests: (validBidRequests = [], bidderRequest) => { - const oRtbRequest = converter.toORTB({bidRequests: validBidRequests, bidderRequest}); + const oRtbRequest = converter.toORTB({ bidRequests: validBidRequests, bidderRequest }); const eids = getEids(validBidRequests[0]); // check for url in params and set in site object diff --git a/modules/sevioBidAdapter.js b/modules/sevioBidAdapter.js index 66bfca681d9..bb3f5f8634a 100644 --- a/modules/sevioBidAdapter.js +++ b/modules/sevioBidAdapter.js @@ -1,9 +1,9 @@ import * as utils from "../src/utils.js"; -import { detectWalletsPresence} from "../libraries/cryptoUtils/wallets.js"; +import { detectWalletsPresence } from "../libraries/cryptoUtils/wallets.js"; import { registerBidder } from "../src/adapters/bidderFactory.js"; import { BANNER, NATIVE } from "../src/mediaTypes.js"; import { config } from "../src/config.js"; -import {getDomComplexity, getPageDescription, getPageTitle} from "../libraries/fpdUtils/pageInfo.js"; +import { getDomComplexity, getPageDescription, getPageTitle } from "../libraries/fpdUtils/pageInfo.js"; import * as converter from '../libraries/ortbConverter/converter.js'; const PREBID_VERSION = '$prebid.version$'; @@ -43,6 +43,39 @@ const normalizeKeywords = (input) => { return []; }; +function resolveDataType(asset) { + if (typeof asset?.data?.type === 'number') { + return asset.data.type; + } + + if (typeof asset?.id === 'number') { + return asset.id; + } + + return null; +} + +// Helper: resolve the "image type" for an asset +// Returns 1 (icon), 3 (image) or null if unknown +function resolveImageType(asset) { + if (!asset) return null; + + // 1) explicit image type in the img block (preferred) + if (typeof asset.img?.type === 'number') return asset.img.type; + + // 2) fallback to data.type (some bidders put the type here) + if (typeof asset.data?.type === 'number') return asset.data.type; + + // 3) last resort: map legacy asset.id values to image types + // (13 -> icon, 14 -> image) — keep this mapping isolated here + if (typeof asset.id === 'number') { + if (asset.id === 13) return 1; // icon + if (asset.id === 14) return 3; // image + } + + return null; +} + const parseNativeAd = function (bid) { try { const nativeAd = JSON.parse(bid.ad); @@ -54,7 +87,8 @@ const parseNativeAd = function (bid) { } if (asset.data) { const value = asset.data.value; - switch (asset.data.type) { + const type = resolveDataType(asset); + switch (type) { case 1: if (value) native.sponsored = value; break; case 2: if (value) native.desc = value; break; case 3: if (value) native.rating = value; break; @@ -71,13 +105,14 @@ const parseNativeAd = function (bid) { } } if (asset.img) { - const { url, w = 0, h = 0, type } = asset.img; + const { url, w = 0, h = 0 } = asset.img; + const imgType = resolveImageType(asset); - if (type === 1 && url) { + if (imgType === 1 && url) { native.icon = url; native.icon_width = w; native.icon_height = h; - } else if (type === 3 && url) { + } else if (imgType === 3 && url) { native.image = url; native.image_width = w; native.image_height = h; @@ -242,7 +277,7 @@ export const spec = { referenceId: bidRequest.params.referenceId, tagId: bidRequest.params.zone, type: detectAdType(bidRequest), - ...(isNative && { nativeRequest: { ver: "1.2", assets: processedAssets || {}} }) + ...(isNative && { nativeRequest: { ver: "1.2", assets: processedAssets || {} } }) }, ], keywords: { diff --git a/modules/sharedIdSystem.ts b/modules/sharedIdSystem.ts index 9405e6c05fb..48875b0fd4d 100644 --- a/modules/sharedIdSystem.ts +++ b/modules/sharedIdSystem.ts @@ -5,16 +5,16 @@ * @requires module:modules/userId */ -import {parseUrl, buildUrl, triggerPixel, logInfo, hasDeviceAccess, generateUUID} from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {VENDORLESS_GVLID} from '../src/consentHandler.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; -import {domainOverrideToRootDomain} from '../libraries/domainOverrideToRootDomain/index.js'; +import { parseUrl, buildUrl, triggerPixel, logInfo, hasDeviceAccess, generateUUID } from '../src/utils.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { VENDORLESS_GVLID } from '../src/consentHandler.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; +import { domainOverrideToRootDomain } from '../libraries/domainOverrideToRootDomain/index.js'; -import type {IdProviderSpec} from "./userId/spec.ts"; +import type { IdProviderSpec } from "./userId/spec.ts"; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: 'sharedId'}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: 'sharedId' }); const COOKIE = 'cookie'; const LOCAL_STORAGE = 'html5'; const OPTOUT_NAME = '_pubcid_optout'; @@ -129,7 +129,7 @@ export const sharedIdSystemSubmodule: IdProviderSpec<'sharedId'> = { return undefined; } logInfo(' Decoded value PubCommonId ' + value); - const idObj = {'pubcid': value as string}; + const idObj = { 'pubcid': value as string }; return idObj; }, getId: function (config = {} as any, consentData, storedId) { @@ -141,7 +141,7 @@ export const sharedIdSystemSubmodule: IdProviderSpec<'sharedId'> = { logInfo('PubCommonId: IDs not provided for coppa requests, exiting PubCommonId'); return; } - const {params: {create = true, pixelUrl} = {}} = config; + const { params: { create = true, pixelUrl } = {} } = config; let newId = storedId; if (!newId) { try { @@ -155,7 +155,7 @@ export const sharedIdSystemSubmodule: IdProviderSpec<'sharedId'> = { if (!newId) newId = (create && hasDeviceAccess()) ? generateUUID() : undefined; } - return {id: newId, callback: getIdCallback(newId, pixelUrl)}; + return { id: newId, callback: getIdCallback(newId, pixelUrl) }; }, /** * performs action to extend an id. There are generally two ways to extend the expiration time @@ -173,20 +173,20 @@ export const sharedIdSystemSubmodule: IdProviderSpec<'sharedId'> = { extendId: function(config = {} as any, consentData, storedId) { if (hasOptedOut()) { logInfo('PubCommonId: Has opted-out'); - return {id: undefined}; + return { id: undefined }; } if (consentData?.coppa) { logInfo('PubCommonId: IDs not provided for coppa requests, exiting PubCommonId'); return; } - const {params: {extend = false, pixelUrl} = {}} = config; + const { params: { extend = false, pixelUrl } = {} } = config; if (extend) { if (pixelUrl) { const callback = queuePixelCallback(pixelUrl, storedId as string); - return {callback: callback}; + return { callback: callback }; } else { - return {id: storedId}; + return { id: storedId }; } } }, @@ -195,7 +195,7 @@ export const sharedIdSystemSubmodule: IdProviderSpec<'sharedId'> = { 'pubcid'(values, config) { const eid: any = { source: 'pubcid.org', - uids: values.map(id => ({id, atype: 1})) + uids: values.map(id => ({ id, atype: 1 })) } if (config?.params?.inserter != null) { eid.inserter = config.params.inserter; diff --git a/modules/sharethroughAnalyticsAdapter.js b/modules/sharethroughAnalyticsAdapter.js index 0857b600b49..68bd577945e 100644 --- a/modules/sharethroughAnalyticsAdapter.js +++ b/modules/sharethroughAnalyticsAdapter.js @@ -1,6 +1,6 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const emptyUrl = ''; const analyticsType = 'endpoint'; diff --git a/modules/shinezBidAdapter.js b/modules/shinezBidAdapter.js index f88360c4c38..d7aa86f12f7 100644 --- a/modules/shinezBidAdapter.js +++ b/modules/shinezBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {makeBaseSpec} from '../libraries/riseUtils/index.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { makeBaseSpec } from '../libraries/riseUtils/index.js'; const BIDDER_CODE = 'shinez'; const BASE_URL = 'https://hb.sweetgum.io/'; diff --git a/modules/shinezRtbBidAdapter.js b/modules/shinezRtbBidAdapter.js index f2034bd1992..4003565bfd9 100644 --- a/modules/shinezRtbBidAdapter.js +++ b/modules/shinezRtbBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { isBidRequestValid, createBuildRequestsFn, @@ -10,7 +10,7 @@ import { const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'shinezRtb'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.sweetgum.io`; diff --git a/modules/showheroes-bsBidAdapter.js b/modules/showheroes-bsBidAdapter.js index 71a017120f0..99b5846e9cf 100644 --- a/modules/showheroes-bsBidAdapter.js +++ b/modules/showheroes-bsBidAdapter.js @@ -96,7 +96,7 @@ export const spec = { return []; } - return converter.fromORTB({response: response.body, request: request.data}).bids; + return converter.fromORTB({ response: response.body, request: request.data }).bids; }, getUserSyncs: (syncOptions, serverResponses) => { const syncs = []; diff --git a/modules/silvermobBidAdapter.js b/modules/silvermobBidAdapter.js index 340dc9c70ac..0f283ecc213 100644 --- a/modules/silvermobBidAdapter.js +++ b/modules/silvermobBidAdapter.js @@ -1,8 +1,8 @@ // import { logMessage } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' +import { ortbConverter } from '../libraries/ortbConverter/converter.js' import { config } from '../src/config.js'; const BIDDER_CODE = 'silvermob'; diff --git a/modules/silverpushBidAdapter.js b/modules/silverpushBidAdapter.js index 46aed11c4ac..1ee5888c67f 100644 --- a/modules/silverpushBidAdapter.js +++ b/modules/silverpushBidAdapter.js @@ -42,7 +42,7 @@ export const spec = { interpretResponse, onBidWon, getRequest: function(endpoint) { - ajax(endpoint, null, undefined, {method: 'GET'}); + ajax(endpoint, null, undefined, { method: 'GET' }); }, getOS: function(ua) { if (ua.indexOf('Windows') !== -1) { return 'Windows'; } else if (ua.match(/(iPhone|iPod|iPad)/)) { return 'iOS'; } else if (ua.indexOf('Mac OS X') !== -1) { return 'macOS'; } else if (ua.match(/Android/)) { return 'Android'; } else if (ua.indexOf('Linux') !== -1) { return 'Linux'; } else { return 'Unknown'; } @@ -209,7 +209,7 @@ function buildBannerImp(bidRequest, imp) { utils.deepSetValue(imp, 'banner.h', bannerSizes[0][1]); } - return {...imp}; + return { ...imp }; } function createRequest(bidRequests, bidderRequest, mediaType) { @@ -245,7 +245,7 @@ function buildVideoOutstreamResponse(bidResponse, context) { bidResponse.renderer.render(bidResponse); } - return {...bidResponse}; + return { ...bidResponse }; } function getBidFloor(bid, bidderRequest) { diff --git a/modules/sizeMapping.js b/modules/sizeMapping.js index ea9e8e2466a..b796015dc90 100644 --- a/modules/sizeMapping.js +++ b/modules/sizeMapping.js @@ -1,8 +1,8 @@ -import {config} from '../src/config.js'; -import {deepAccess, deepClone, deepSetValue, getWindowTop, logInfo, logWarn} from '../src/utils.js'; +import { config } from '../src/config.js'; +import { deepAccess, deepClone, deepSetValue, getWindowTop, logInfo, logWarn } from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {setupAdUnitMediaTypes} from '../src/adapterManager.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { setupAdUnitMediaTypes } from '../src/adapterManager.js'; let sizeConfig = []; @@ -36,9 +36,9 @@ config.getConfig('sizeConfig', config => setSizeConfig(config.sizeConfig)); */ export function getLabels(bidOrAdUnit, activeLabels) { if (bidOrAdUnit.labelAll) { - return {labelAll: true, labels: bidOrAdUnit.labelAll, activeLabels}; + return { labelAll: true, labels: bidOrAdUnit.labelAll, activeLabels }; } - return {labelAll: false, labels: bidOrAdUnit.labelAny, activeLabels}; + return { labelAll: false, labels: bidOrAdUnit.labelAny, activeLabels }; } /** @@ -76,12 +76,12 @@ if (FEATURES.VIDEO) { * @returns {Object} return.mediaTypes - The media types object. * @returns {Object} [return.filterResults] - The filter results before and after applying size filtering. */ -export function resolveStatus({labels = [], labelAll = false, activeLabels = []} = {}, mediaTypes, configs = sizeConfig) { +export function resolveStatus({ labels = [], labelAll = false, activeLabels = [] } = {}, mediaTypes, configs = sizeConfig) { const maps = evaluateSizeConfig(configs); let filtered = false; let hasSize = false; - const filterResults = {before: {}, after: {}}; + const filterResults = { before: {}, after: {} }; if (maps.shouldFilter) { Object.entries(SIZE_PROPS).forEach(([mediaType, sizeProp]) => { diff --git a/modules/sizeMappingV2.js b/modules/sizeMappingV2.js index c234c039ac2..70b848a1419 100644 --- a/modules/sizeMappingV2.js +++ b/modules/sizeMappingV2.js @@ -15,8 +15,8 @@ import { logWarn } from '../src/utils.js'; -import {getHook} from '../src/hook.js'; -import {adUnitSetupChecks} from '../src/prebid.js'; +import { getHook } from '../src/hook.js'; +import { adUnitSetupChecks } from '../src/prebid.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').AdUnit} AdUnit diff --git a/modules/slimcutBidAdapter.js b/modules/slimcutBidAdapter.js index e62d7ac5871..0604e3c8eae 100644 --- a/modules/slimcutBidAdapter.js +++ b/modules/slimcutBidAdapter.js @@ -1,4 +1,4 @@ -import {getBidIdParameter, getValue, parseSizesInput} from '../src/utils.js'; +import { getBidIdParameter, getValue, parseSizesInput } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; @@ -16,7 +16,7 @@ const BIDDER_CODE = 'slimcut'; const ENDPOINT_URL = 'https://sb.freeskreen.com/pbr'; export const spec = { code: BIDDER_CODE, - aliases: [{ code: 'scm'}], + aliases: [{ code: 'scm' }], supportedMediaTypes: ['video', 'banner'], /** * Determines whether or not the given bid request is valid. diff --git a/modules/smaatoBidAdapter.js b/modules/smaatoBidAdapter.js index 03199e99d52..28fbdf61ae7 100644 --- a/modules/smaatoBidAdapter.js +++ b/modules/smaatoBidAdapter.js @@ -1,13 +1,13 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {deepAccess, deepSetValue, isEmpty, isNumber, logError, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {ADPOD, BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {NATIVE_IMAGE_TYPES} from '../src/constants.js'; -import {getAdUnitSizes} from '../libraries/sizeUtils/sizeUtils.js'; -import {fill} from '../libraries/appnexusUtils/anUtils.js'; -import {chunk} from '../libraries/chunk/chunk.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { deepAccess, deepSetValue, isEmpty, isNumber, logError, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { ADPOD, BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { NATIVE_IMAGE_TYPES } from '../src/constants.js'; +import { getAdUnitSizes } from '../libraries/sizeUtils/sizeUtils.js'; +import { fill } from '../libraries/appnexusUtils/anUtils.js'; +import { chunk } from '../libraries/chunk/chunk.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -86,14 +86,15 @@ export const spec = { // separate requests per mediaType SUPPORTED_MEDIA_TYPES.forEach(mediaType => { if ((bid.mediaTypes && bid.mediaTypes[mediaType]) || (mediaType === NATIVE && bid.nativeOrtbRequest)) { - const data = converter.toORTB({bidderRequest, bidRequests: [bid], context: {mediaType}}); + const data = converter.toORTB({ bidderRequest, bidRequests: [bid], context: { mediaType } }); requests.push({ method: 'POST', url: bid.params.endpoint || SMAATO_ENDPOINT, data: JSON.stringify(data), options: { withCredentials: true, - crossOrigin: true}, + crossOrigin: true + }, bidderRequest }) } @@ -143,7 +144,7 @@ export const spec = { advertiserDomains: bid.adomain, networkName: bid.bidderName, agencyId: seatbid.seat, - ...(bid.ext?.dsa && {dsa: bid.ext.dsa}) + ...(bid.ext?.dsa && { dsa: bid.ext.dsa }) } }; @@ -470,7 +471,7 @@ function createAdPodImp(imp, videoMediaType) { } function getAdPodNumberOfPlacements(videoMediaType) { - const {adPodDurationSec, durationRangeSec, requireExactDuration} = videoMediaType + const { adPodDurationSec, durationRangeSec, requireExactDuration } = videoMediaType const minAllowedDuration = Math.min(...durationRangeSec) const numberOfPlacements = Math.floor(adPodDurationSec / minAllowedDuration) @@ -509,7 +510,7 @@ const addOptionalAdpodParameters = (videoMediaType) => { function getBidFloor(bidRequest, mediaType, sizes) { if (typeof bidRequest.getFloor === 'function') { const size = sizes.length === 1 ? sizes[0] : '*'; - const floor = bidRequest.getFloor({currency: CURRENCY, mediaType: mediaType, size: size}); + const floor = bidRequest.getFloor({ currency: CURRENCY, mediaType: mediaType, size: size }); if (floor && !isNaN(floor.floor) && (floor.currency === CURRENCY)) { return floor.floor; } diff --git a/modules/smarthubBidAdapter.js b/modules/smarthubBidAdapter.js index 2a896a92499..5b7a8fba1fe 100644 --- a/modules/smarthubBidAdapter.js +++ b/modules/smarthubBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import { buildPlacementProcessingFunction, buildRequestsBase, @@ -15,19 +15,19 @@ const SYNC_URLS = { }; const ALIASES = { - 'attekmi': {area: '1', pid: '300'}, - 'markapp': {area: '4', pid: '360'}, - 'jdpmedia': {area: '1', pid: '382'}, - 'tredio': {area: '4', pid: '337'}, - 'felixads': {area: '1', pid: '406'}, - 'artechnology': {area: '1', pid: '420'}, - 'adinify': {area: '1', pid: '424'}, - 'addigi': {area: '1', pid: '425'}, - 'jambojar': {area: '1', pid: '426'}, - 'anzu': {area: '1', pid: '445'}, - 'amcom': {area: '1', pid: '397'}, - 'adastra': {area: '1', pid: '33'}, - 'radiantfusion': {area: '1', pid: '455'}, + 'attekmi': { area: '1', pid: '300' }, + 'markapp': { area: '4', pid: '360' }, + 'jdpmedia': { area: '1', pid: '382' }, + 'tredio': { area: '4', pid: '337' }, + 'felixads': { area: '1', pid: '406' }, + 'artechnology': { area: '1', pid: '420' }, + 'adinify': { area: '1', pid: '424' }, + 'addigi': { area: '1', pid: '425' }, + 'jambojar': { area: '1', pid: '426' }, + 'anzu': { area: '1', pid: '445' }, + 'amcom': { area: '1', pid: '397' }, + 'adastra': { area: '1', pid: '33' }, + 'radiantfusion': { area: '1', pid: '455' }, }; const BASE_URLS = { diff --git a/modules/smarticoBidAdapter.js b/modules/smarticoBidAdapter.js index cb4379263ff..0b81735cbe1 100644 --- a/modules/smarticoBidAdapter.js +++ b/modules/smarticoBidAdapter.js @@ -1,5 +1,5 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const SMARTICO_CONFIG = { bidRequestUrl: 'https://trmads.eu/preBidRequest', @@ -66,7 +66,7 @@ export const spec = { url: SMARTICO_CONFIG.bidRequestUrl, bids: validBidRequests, // TODO: fix auctionId leak: https://github.com/prebid/Prebid.js/issues/9781 - data: {bidParams: bidParams, auctionId: bidderRequest.auctionId} + data: { bidParams: bidParams, auctionId: bidderRequest.auctionId } } return ServerRequestObjects; }, diff --git a/modules/smartxBidAdapter.js b/modules/smartxBidAdapter.js index 00f8616a665..a012f2ca2f4 100644 --- a/modules/smartxBidAdapter.js +++ b/modules/smartxBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { logError, deepAccess, diff --git a/modules/smartyadsAnalyticsAdapter.js b/modules/smartyadsAnalyticsAdapter.js index eab9995d238..b666cc9294b 100644 --- a/modules/smartyadsAnalyticsAdapter.js +++ b/modules/smartyadsAnalyticsAdapter.js @@ -84,7 +84,7 @@ const auctionHandler = (eventType, data) => { } const bidHandler = (eventType, bid) => { - const bids = bid.length ? bid : [ bid ]; + const bids = bid.length ? bid : [bid]; for (const bidObj of bids) { let bidToSend; @@ -114,7 +114,7 @@ const onBidderError = (data) => { error: data.error, bidderRequests: data?.bidderRequests?.length ? data.bidderRequests.filter(request => request.bidderCode === BIDDER_CODE) - : [ data.bidderRequest ] + : [data.bidderRequest] }); } diff --git a/modules/smartytechBidAdapter.js b/modules/smartytechBidAdapter.js index 373faebf5a4..1fc3ec5801c 100644 --- a/modules/smartytechBidAdapter.js +++ b/modules/smartytechBidAdapter.js @@ -1,10 +1,10 @@ -import {buildUrl, deepAccess, isArray, generateUUID} from '../src/utils.js' +import { buildUrl, deepAccess, isArray, generateUUID } from '../src/utils.js' import { BANNER, VIDEO } from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {chunk} from '../libraries/chunk/chunk.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {findRootDomain} from '../src/fpd/rootDomain.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { chunk } from '../libraries/chunk/chunk.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { findRootDomain } from '../src/fpd/rootDomain.js'; const BIDDER_CODE = 'smartytech'; export const ENDPOINT_PROTOCOL = 'https'; @@ -16,7 +16,7 @@ const AUID_COOKIE_NAME = '_smartytech_auid'; const AUID_COOKIE_EXPIRATION_DAYS = 1825; // 5 years // Storage manager for cookies -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); /** * Get or generate Alias User ID (auId) @@ -47,7 +47,7 @@ export function getAliasUserId() { } export const spec = { - supportedMediaTypes: [ BANNER, VIDEO ], + supportedMediaTypes: [BANNER, VIDEO], code: BIDDER_CODE, isBidRequestValid: function (bidRequest) { diff --git a/modules/smilewantedBidAdapter.js b/modules/smilewantedBidAdapter.js index 5e47fe3cf47..0bb4ba86eff 100644 --- a/modules/smilewantedBidAdapter.js +++ b/modules/smilewantedBidAdapter.js @@ -1,10 +1,10 @@ -import {deepAccess, deepClone, isArray, isFn, isPlainObject, logError, logWarn} from '../src/utils.js'; -import {Renderer} from '../src/Renderer.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; -import {serializeSupplyChain} from '../libraries/schainSerializer/schainSerializer.js' -import {convertOrtbRequestToProprietaryNative, toOrtbNativeRequest, toLegacyResponse} from '../src/native.js'; +import { deepAccess, deepClone, isArray, isFn, isPlainObject, logError, logWarn } from '../src/utils.js'; +import { Renderer } from '../src/Renderer.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; +import { serializeSupplyChain } from '../libraries/schainSerializer/schainSerializer.js' +import { convertOrtbRequestToProprietaryNative, toOrtbNativeRequest, toLegacyResponse } from '../src/native.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; const BIDDER_CODE = 'smilewanted'; diff --git a/modules/snigelBidAdapter.js b/modules/snigelBidAdapter.js index 29534ae7318..15d09b2fa26 100644 --- a/modules/snigelBidAdapter.js +++ b/modules/snigelBidAdapter.js @@ -1,9 +1,9 @@ -import {getDNT} from '../libraries/dnt/index.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {deepAccess, isArray, isFn, isPlainObject, inIframe, generateUUID} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { getDNT } from '../libraries/dnt/index.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { deepAccess, isArray, isFn, isPlainObject, inIframe, generateUUID } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; import { getViewportSize } from '../libraries/viewport/viewport.js'; const BIDDER_CODE = 'snigel'; @@ -15,7 +15,7 @@ const FLOOR_MATCH_ALL_SIZES = '*'; const SESSION_ID_KEY = '_sn_session_pba'; const getConfig = config.getConfig; -const storageManager = getStorageManager({bidderCode: BIDDER_CODE}); +const storageManager = getStorageManager({ bidderCode: BIDDER_CODE }); const refreshes = {}; const placementCounters = {}; const pageViewStart = new Date().getTime(); @@ -109,7 +109,7 @@ export const spec = { getUserSyncs: function (syncOptions, responses, gdprConsent, uspConsent, gppConsent) { const syncUrl = getSyncUrl(responses || []); if (syncUrl && syncOptions.iframeEnabled) { - return [{type: 'iframe', url: getSyncEndpoint(syncUrl, gdprConsent, uspConsent, gppConsent)}]; + return [{ type: 'iframe', url: getSyncEndpoint(syncUrl, gdprConsent, uspConsent, gppConsent) }]; } }, }; diff --git a/modules/sonaradsBidAdapter.js b/modules/sonaradsBidAdapter.js index b1699029f21..2754b3f6062 100644 --- a/modules/sonaradsBidAdapter.js +++ b/modules/sonaradsBidAdapter.js @@ -1,8 +1,8 @@ -import {deepSetValue, isFn, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { deepSetValue, isFn, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/sovrnBidAdapter.js b/modules/sovrnBidAdapter.js index 2e38a88c2f4..285cd43d1b3 100644 --- a/modules/sovrnBidAdapter.js +++ b/modules/sovrnBidAdapter.js @@ -39,6 +39,7 @@ export const spec = { code: 'sovrn', supportedMediaTypes: [BANNER, VIDEO], gvlid: 13, + alwaysHasCapacity: true, /** * Check if the bid is a valid zone ID in either number or string form @@ -102,7 +103,7 @@ export const spec = { let bidSizes = deepAccess(bid, 'mediaTypes.banner.sizes') || bid.sizes bidSizes = (isArray(bidSizes) && isArray(bidSizes[0])) ? bidSizes : [bidSizes] bidSizes = bidSizes.filter(size => isArray(size)) - const processedSizes = bidSizes.map(size => ({w: parseInt(size[0], 10), h: parseInt(size[1], 10)})) + const processedSizes = bidSizes.map(size => ({ w: parseInt(size[0], 10), h: parseInt(size[1], 10) })) imp.banner = { format: processedSizes, @@ -195,7 +196,7 @@ export const spec = { method: 'POST', url: url, data: JSON.stringify(sovrnBidReq), - options: {contentType: 'text/plain'} + options: { contentType: 'text/plain' } } } catch (e) { logError('Could not build bidrequest, error deatils:', e); @@ -207,7 +208,7 @@ export const spec = { * @param {*} param0 A successful response from Sovrn. * @return {Bid[]} An array of formatted bids. */ - interpretResponse: function({ body: {id, seatbid} }) { + interpretResponse: function({ body: { id, seatbid } }) { if (!id || !seatbid || !Array.isArray(seatbid)) return [] try { diff --git a/modules/sparteoBidAdapter.js b/modules/sparteoBidAdapter.js index 13cb0198594..9332e99a6f5 100644 --- a/modules/sparteoBidAdapter.js +++ b/modules/sparteoBidAdapter.js @@ -226,7 +226,7 @@ export const spec = { }, buildRequests: function (bidRequests, bidderRequest) { - const payload = converter.toORTB({bidRequests, bidderRequest}) + const payload = converter.toORTB({ bidRequests, bidderRequest }) const endpoint = bidRequests[0].params.endpoint ? bidRequests[0].params.endpoint : REQUEST_URL; const url = replaceMacros(payload, endpoint); @@ -239,7 +239,7 @@ export const spec = { }, interpretResponse: function (serverResponse, requests) { - const bids = converter.fromORTB({response: serverResponse.body, request: requests.data}).bids; + const bids = converter.fromORTB({ response: serverResponse.body, request: requests.data }).bids; return bids; }, diff --git a/modules/ssmasBidAdapter.js b/modules/ssmasBidAdapter.js index 29d3b787ad1..2c4a2bff135 100644 --- a/modules/ssmasBidAdapter.js +++ b/modules/ssmasBidAdapter.js @@ -2,7 +2,7 @@ import { BANNER } from '../src/mediaTypes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { triggerPixel, deepSetValue } from '../src/utils.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; -import {config} from '../src/config.js'; +import { config } from '../src/config.js'; export const SSMAS_CODE = 'ssmas'; const SSMAS_SERVER = 'ads.ssmas.com'; diff --git a/modules/sspBCBidAdapter.js b/modules/sspBCBidAdapter.js index 5ce8fb34492..7a7275d5ff2 100644 --- a/modules/sspBCBidAdapter.js +++ b/modules/sspBCBidAdapter.js @@ -792,8 +792,8 @@ const spec = { }, getUserSyncs(syncOptions, _, gdprConsent = {}) { - const {iframeEnabled, pixelEnabled} = syncOptions; - const {gdprApplies, consentString = ''} = gdprConsent; + const { iframeEnabled, pixelEnabled } = syncOptions; + const { gdprApplies, consentString = '' } = gdprConsent; const mySyncs = []; if (iframeEnabled) { mySyncs.push({ diff --git a/modules/ssp_genieeBidAdapter.js b/modules/ssp_genieeBidAdapter.js index c4464f0f59a..409c81b3e54 100644 --- a/modules/ssp_genieeBidAdapter.js +++ b/modules/ssp_genieeBidAdapter.js @@ -16,12 +16,12 @@ const BIDDER_CODE = 'ssp_geniee'; export const BANNER_ENDPOINT = 'https://aladdin.genieesspv.jp/yie/ld/api/ad_call/v2'; export const USER_SYNC_ENDPOINT_IMAGE = 'https://cs.gssprt.jp/yie/ld/mcs'; export const USER_SYNC_ENDPOINT_IFRAME = 'https://aladdin.genieesspv.jp/yie/ld'; -const SUPPORTED_MEDIA_TYPES = [ BANNER ]; +const SUPPORTED_MEDIA_TYPES = [BANNER]; const DEFAULT_CURRENCY = 'JPY'; const ALLOWED_CURRENCIES = ['USD', 'JPY']; const NET_REVENUE = true; const MODULE_NAME = `ssp_geniee`; -export const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME}) +export const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_NAME }) /** * List of keys for geparams (parameters we use) @@ -124,7 +124,7 @@ function hasParamsNotBlankString(params, key) { ); } -export const buildExtuidQuery = ({id5, imuId}) => { +export const buildExtuidQuery = ({ id5, imuId }) => { const params = [ ...(id5 ? [`id5:${id5}`] : []), ...(imuId ? [`im:${imuId}`] : []), @@ -233,7 +233,7 @@ function makeCommonRequestData(bid, geparameter, refererInfo) { // imuid, id5 const id5 = utils.deepAccess(bid, 'userId.id5id.uid'); const imuId = utils.deepAccess(bid, 'userId.imuid'); - const extuidQuery = buildExtuidQuery({id5, imuId}); + const extuidQuery = buildExtuidQuery({ id5, imuId }); if (extuidQuery) data.extuid = extuidQuery; // makeUAQuery diff --git a/modules/stackadaptBidAdapter.js b/modules/stackadaptBidAdapter.js index 4f866c217d2..86303e17232 100644 --- a/modules/stackadaptBidAdapter.js +++ b/modules/stackadaptBidAdapter.js @@ -2,7 +2,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { ortbConverter } from '../libraries/ortbConverter/converter.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { deepSetValue, logWarn, parseSizesInput, isNumber, isInteger, replaceAuctionPrice, formatQS, isFn, isPlainObject } from '../src/utils.js'; -import {getUserSyncParams} from '../libraries/userSyncUtils/userSyncUtils.js'; +import { getUserSyncParams } from '../libraries/userSyncUtils/userSyncUtils.js'; const BIDDER_CODE = 'stackadapt'; const ENDPOINT_URL = 'https://pjs.srv.stackadapt.com/br'; diff --git a/modules/startioBidAdapter.js b/modules/startioBidAdapter.js index 74629f2cc9c..fe1d10bf9a2 100644 --- a/modules/startioBidAdapter.js +++ b/modules/startioBidAdapter.js @@ -112,7 +112,7 @@ export const spec = { const data = converter.toORTB({ bidRequests: [bidRequest], bidderRequest, - context: {mediaType, bidParams: bidRequest.params} + context: { mediaType, bidParams: bidRequest.params } }); return { diff --git a/modules/stnBidAdapter.js b/modules/stnBidAdapter.js index 62d82b8d4b2..0508d50e18c 100644 --- a/modules/stnBidAdapter.js +++ b/modules/stnBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {makeBaseSpec} from '../libraries/riseUtils/index.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { makeBaseSpec } from '../libraries/riseUtils/index.js'; const BIDDER_CODE = 'stn'; const BASE_URL = 'https://hb.stngo.com/'; diff --git a/modules/storageControl.ts b/modules/storageControl.ts index 93411fba3ac..188ece48107 100644 --- a/modules/storageControl.ts +++ b/modules/storageControl.ts @@ -1,5 +1,5 @@ -import {config} from '../src/config.js'; -import {metadata} from '../libraries/metadata/metadata.js'; +import { config } from '../src/config.js'; +import { metadata } from '../libraries/metadata/metadata.js'; import { ACTIVITY_PARAM_COMPONENT, ACTIVITY_PARAM_COMPONENT_NAME, @@ -13,14 +13,14 @@ import { STORAGE_TYPE_LOCALSTORAGE, type StorageDisclosure as Disclosure } from '../src/storageManager.js'; -import {logWarn, uniques} from '../src/utils.js'; -import {registerActivityControl} from '../src/activities/rules.js'; -import {ACTIVITY_ACCESS_DEVICE} from '../src/activities/activities.js'; -import {addApiMethod} from "../src/prebid.ts"; +import { logWarn, uniques } from '../src/utils.js'; +import { registerActivityControl } from '../src/activities/rules.js'; +import { ACTIVITY_ACCESS_DEVICE } from '../src/activities/activities.js'; +import { addApiMethod } from "../src/prebid.ts"; // @ts-expect-error the ts compiler is confused by build-time renaming of summary.mjs to summary.js, reassure it // eslint-disable-next-line prebid/validate-imports -import {getStorageDisclosureSummary} from "../libraries/storageDisclosure/summary.js"; -import {getGlobal} from "../src/prebidGlobal.ts"; +import { getStorageDisclosureSummary } from "../libraries/storageDisclosure/summary.js"; +import { getGlobal } from "../src/prebidGlobal.ts"; export const ENFORCE_STRICT = 'strict'; export const ENFORCE_ALIAS = 'allowAliases'; @@ -83,9 +83,9 @@ export function checkDisclosure(params, getMatchingDisclosures = getDisclosures) if (disclosures == null) { reason = `Cannot determine if storage key "${key}" is disclosed by "${component}" because the necessary metadata is missing - was it included in the build?` } else { - const {disclosureURLs, matches} = disclosures; + const { disclosureURLs, matches } = disclosures; const moduleName = params[ACTIVITY_PARAM_COMPONENT_NAME] - for (const {componentName} of matches) { + for (const { componentName } of matches) { if (componentName === moduleName) { disclosed = true; } else { @@ -113,11 +113,11 @@ export function checkDisclosure(params, getMatchingDisclosures = getDisclosures) export function storageControlRule(getEnforcement = () => enforcement, check = checkDisclosure) { return function (params) { - const {disclosed, parent, reason} = check(params); + const { disclosed, parent, reason } = check(params); if (disclosed === null) return; if (!disclosed) { const enforcement = getEnforcement(); - if (enforcement === ENFORCE_STRICT || (enforcement === ENFORCE_ALIAS && !parent)) return {allow: false, reason}; + if (enforcement === ENFORCE_STRICT || (enforcement === ENFORCE_ALIAS && !parent)) return { allow: false, reason }; if (reason) { logWarn('storageControl:', reason); } @@ -185,7 +185,7 @@ export function dynamicDisclosureCollector() { } } -const {hook: discloseStorageHook, getDisclosures: dynamicDisclosures} = dynamicDisclosureCollector(); +const { hook: discloseStorageHook, getDisclosures: dynamicDisclosures } = dynamicDisclosureCollector(); discloseStorageUse.before(discloseStorageHook); export type StorageDisclosure = Disclosure & { diff --git a/modules/stroeerCoreBidAdapter.js b/modules/stroeerCoreBidAdapter.js index aa9f656aa24..f04080709a0 100644 --- a/modules/stroeerCoreBidAdapter.js +++ b/modules/stroeerCoreBidAdapter.js @@ -1,8 +1,8 @@ -import {buildUrl, deepAccess, deepSetValue, generateUUID, getWinDimensions, getWindowSelf, getWindowTop, isEmpty, isStr, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getBoundingClientRect} from '../libraries/boundingClientRect/boundingClientRect.js'; -import {getGlobal} from '../src/prebidGlobal.js'; +import { buildUrl, deepAccess, deepSetValue, generateUUID, getWinDimensions, getWindowSelf, getWindowTop, isEmpty, isStr, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; +import { getGlobal } from '../src/prebidGlobal.js'; const GVL_ID = 136; const BIDDER_CODE = 'stroeerCore'; @@ -98,7 +98,7 @@ export const spec = { return { method: 'POST', url: buildEndpointUrl(anyBid.params), - data: {...basePayload, bids: [...bannerBids, ...videoBids]} + data: { ...basePayload, bids: [...bannerBids, ...videoBids] } }; }, @@ -118,7 +118,7 @@ export const spec = { currency: 'EUR', netRevenue: true, creativeId: '', - meta: {...bidResponse.meta}, + meta: { ...bidResponse.meta }, mediaType, }; @@ -181,12 +181,12 @@ const elementInView = (elementId) => { return undefined; } -const buildEndpointUrl = ({host: hostname = DEFAULT_HOST, port = DEFAULT_PORT, securePort, path: pathname = DEFAULT_PATH}) => { +const buildEndpointUrl = ({ host: hostname = DEFAULT_HOST, port = DEFAULT_PORT, securePort, path: pathname = DEFAULT_PATH }) => { if (securePort) { port = securePort; } - return buildUrl({protocol: 'https', hostname, port, pathname}); + return buildUrl({ protocol: 'https', hostname, port, pathname }); } const getGdprParams = gdprConsent => { @@ -261,7 +261,7 @@ const createFloorPriceObject = (mediaType, sizes, bidRequest) => { mediaType: mediaType, size: [size[0], size[1]] }) || {}; - return {...floor, size}; + return { ...floor, size }; }); const floorWithCurrency = (([defaultFloor].concat(sizeFloors)) || []).find(floor => floor.currency); diff --git a/modules/stvBidAdapter.js b/modules/stvBidAdapter.js index 634eff58c05..45fc0791be4 100644 --- a/modules/stvBidAdapter.js +++ b/modules/stvBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, logMessage} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { deepAccess, logMessage } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { handleSyncUrls, diff --git a/modules/symitriAnalyticsAdapter.js b/modules/symitriAnalyticsAdapter.js index 4e2d1e070e6..6b4792e95c8 100644 --- a/modules/symitriAnalyticsAdapter.js +++ b/modules/symitriAnalyticsAdapter.js @@ -2,7 +2,7 @@ import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; import { logMessage } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; const analyticsType = 'endpoint'; const url = 'https://ProdSymPrebidEventhub1.servicebus.windows.net/prebid-said-1/messages'; @@ -11,7 +11,7 @@ const { BID_WON } = EVENTS; let initOptions; -const symitriAnalytics = Object.assign(adapter({url, analyticsType}), { +const symitriAnalytics = Object.assign(adapter({ url, analyticsType }), { track({ eventType, args }) { switch (eventType) { case BID_WON: @@ -41,7 +41,7 @@ function sendEvent(payload) { ajax(url, cb, body, { method: 'POST', - customHeaders: {'Content-Type': 'application/atom+xml;type=entry;charset=utf-8', 'Authorization': initOptions.apiAuthToken} + customHeaders: { 'Content-Type': 'application/atom+xml;type=entry;charset=utf-8', 'Authorization': initOptions.apiAuthToken } }); } } catch (err) { logMessage('##### symitriAnalytics :: error' + err) } diff --git a/modules/symitriDapRtdProvider.js b/modules/symitriDapRtdProvider.js index ace251872ff..099f428323b 100644 --- a/modules/symitriDapRtdProvider.js +++ b/modules/symitriDapRtdProvider.js @@ -5,12 +5,12 @@ * @module modules/symitriDapRtdProvider * @requires module:modules/realTimeData */ -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {submodule} from '../src/hook.js'; -import {isPlainObject, mergeDeep, logMessage, logInfo, logError} from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { submodule } from '../src/hook.js'; +import { isPlainObject, mergeDeep, logMessage, logInfo, logError } from '../src/utils.js'; import { loadExternalScript } from '../src/adloader.js'; -import {MODULE_TYPE_RTD} from '../src/activities/modules.js'; +import { MODULE_TYPE_RTD } from '../src/activities/modules.js'; /** * @typedef {import('../modules/rtdModule/index.js').RtdSubmodule} RtdSubmodule @@ -28,7 +28,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { const DAP_MAX_RETRY_TOKENIZE = 1; const DAP_CLIENT_ENTROPY = 'dap_client_entropy' - const storage = getStorageManager({moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME}); + const storage = getStorageManager({ moduleType: MODULE_TYPE_RTD, moduleName: SUBMODULE_NAME }); let dapRetryTokenize = 0; /** @@ -186,7 +186,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { api_version: rtdConfig.params.apiVersion, domain: rtdConfig.params.domain, segtax: rtdConfig.params.segtax, - identity: {type: rtdConfig.params.identityType, value: rtdConfig.params.identityValue}, + identity: { type: rtdConfig.params.identityType, value: rtdConfig.params.identityValue }, }; let refreshMembership = true; const token = dapUtils.dapGetTokenFromLocalStorage(); @@ -229,7 +229,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { // Trigger a refresh const now = Math.round(Date.now() / 1000.0); // in seconds const item = {} - const configAsync = {...config}; + const configAsync = { ...config }; dapUtils.dapTokenize(configAsync, config.identity, onDone, function(token, status, xhr, onDone) { item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; @@ -284,7 +284,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { dapRefreshMembership: function(ortb2, config, token, onDone) { const now = Math.round(Date.now() / 1000.0); // in seconds const item = {} - const configAsync = {...config}; + const configAsync = { ...config }; dapUtils.dapMembership(configAsync, token, onDone, function(membership, status, xhr, onDone) { item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; @@ -332,7 +332,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { dapRefreshEncryptedMembership: function(ortb2, config, token, onDone) { const now = Math.round(Date.now() / 1000.0); // in seconds const item = {}; - const configAsync = {...config}; + const configAsync = { ...config }; dapUtils.dapEncryptedMembership(configAsync, token, onDone, function(encToken, status, xhr, onDone) { item.expires_at = now + DAP_DEFAULT_TOKEN_TTL; @@ -528,7 +528,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { if (config === null || config === undefined) { onError(null, 'Invalid config object', 'ClientError', onDone); - return [ config, true ]; + return [config, true]; } if (!('api_version' in config) || (typeof (config.api_version) === 'string' && config.api_version.length === 0)) { @@ -537,22 +537,22 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { if (typeof (config.api_version) !== 'string') { onError(null, "Invalid api_version: must be a string like 'x1', etc.", 'ClientError', onDone); - return [ config, true ]; + return [config, true]; } if (!(('api_hostname') in config) || typeof (config.api_hostname) !== 'string' || config.api_hostname.length === 0) { onError(null, 'Invalid api_hostname: must be a non-empty string', 'ClientError', onDone); - return [ config, true ]; + return [config, true]; } if (token) { if (typeof (token) !== 'string') { onError(null, 'Invalid token: must be a non-null string', 'ClientError', onDone); - return [ config, true ]; + return [config, true]; } } - return [ config, false ]; + return [config, false]; }, addIdentifier: async function(identity, apiParams) { @@ -606,7 +606,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { */ dapTokenize: function(config, identity, onDone, onSuccess = null, onError = null) { let hasTokenizeError; - [ config, hasTokenizeError ] = this.dapValidationHelper(config, onDone, null, onError); + [config, hasTokenizeError] = this.dapValidationHelper(config, onDone, null, onError); if (hasTokenizeError) { return; } if (typeof (config.domain) !== 'string') { @@ -739,7 +739,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { */ dapMembership: function(config, token, onDone, onSuccess = null, onError = null) { let hasMembershipError; - [ config, hasMembershipError ] = this.dapValidationHelper(config, onDone, token, onError); + [config, hasMembershipError] = this.dapValidationHelper(config, onDone, token, onError); if (hasMembershipError) { return; } if (typeof (config.domain) !== 'string') { @@ -803,7 +803,7 @@ export function createRtdProvider(moduleName, moduleCode, headerPrefix) { */ dapEncryptedMembership: function(config, token, onDone, onSuccess = null, onError = null) { let hasEncryptedMembershipError; - [ config, hasEncryptedMembershipError ] = this.dapValidationHelper(config, onDone, token, onError); + [config, hasEncryptedMembershipError] = this.dapValidationHelper(config, onDone, token, onError); if (hasEncryptedMembershipError) { return; } const cb = { diff --git a/modules/taboolaBidAdapter.js b/modules/taboolaBidAdapter.js index 421ddbd256b..a82cdf0adf0 100644 --- a/modules/taboolaBidAdapter.js +++ b/modules/taboolaBidAdapter.js @@ -1,21 +1,22 @@ 'use strict'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {deepSetValue, getWindowSelf, replaceAuctionPrice, isArray, safeJSONParse, isPlainObject, getWinDimensions} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {ajax} from '../src/ajax.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {getConnectionType} from '../libraries/connectionInfo/connectionUtils.js'; -import {getViewportCoordinates} from '../libraries/viewport/viewport.js'; -import {percentInView} from '../libraries/percentInView/percentInView.js'; -import {getBoundingClientRect} from '../libraries/boundingClientRect/boundingClientRect.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { deepSetValue, getWindowSelf, replaceAuctionPrice, isArray, safeJSONParse, isPlainObject, getWinDimensions } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { ajax } from '../src/ajax.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { getConnectionType } from '../libraries/connectionInfo/connectionUtils.js'; +import { getViewportCoordinates } from '../libraries/viewport/viewport.js'; +import { percentInView } from '../libraries/percentInView/percentInView.js'; +import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; const BIDDER_CODE = 'taboola'; const GVLID = 42; const CURRENCY = 'USD'; -export const END_POINT_URL = 'https://display.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; +export const BANNER_ENDPOINT_URL = 'https://display.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; +export const NATIVE_ENDPOINT_URL = 'https://native.bidder.taboola.com/OpenRTB/TaboolaHB/auction'; export const USER_SYNC_IMG_URL = 'https://trc.taboola.com/sg/prebidJS/1/cm'; export const USER_SYNC_IFRAME_URL = 'https://cdn.taboola.com/scripts/prebid_iframe_sync.html'; const USER_ID = 'user-id'; @@ -34,9 +35,9 @@ export const EVENT_ENDPOINT = 'https://beacon.bidder.taboola.com'; * 4. new user set it to 0 */ export const userData = { - storageManager: getStorageManager({bidderCode: BIDDER_CODE}), + storageManager: getStorageManager({ bidderCode: BIDDER_CODE }), getUserId: () => { - const {getFromLocalStorage, getFromCookie, getFromTRC} = userData; + const { getFromLocalStorage, getFromCookie, getFromTRC } = userData; try { return getFromLocalStorage() || getFromCookie() || getFromTRC(); @@ -45,7 +46,7 @@ export const userData = { } }, getFromCookie() { - const {cookiesAreEnabled, getCookie} = userData.storageManager; + const { cookiesAreEnabled, getCookie } = userData.storageManager; if (cookiesAreEnabled()) { const cookieData = getCookie(COOKIE_KEY); let userId; @@ -78,7 +79,7 @@ export const userData = { return value; }, getFromLocalStorage() { - const {hasLocalStorage, localStorageIsEnabled, getDataFromLocalStorage} = userData.storageManager; + const { hasLocalStorage, localStorageIsEnabled, getDataFromLocalStorage } = userData.storageManager; if (hasLocalStorage() && localStorageIsEnabled()) { return getDataFromLocalStorage(STORAGE_KEY); @@ -169,12 +170,11 @@ export function getElementSignals(adUnitCode) { const converter = ortbConverter({ context: { netRevenue: true, - mediaType: BANNER, ttl: 300 }, imp(buildImp, bidRequest, context) { const imp = buildImp(bidRequest, context); - fillTaboolaImpData(bidRequest, imp); + fillTaboolaImpData(bidRequest, imp, context); return imp; }, request(buildRequest, imps, bidderRequest, context) { @@ -183,12 +183,21 @@ const converter = ortbConverter({ return reqData; }, bidResponse(buildBidResponse, bid, context) { + if (context.mediaType === NATIVE) { + const admObj = safeJSONParse(bid.adm); + if (admObj?.native) { + bid.adm = JSON.stringify(admObj.native); + } + } + const bidResponse = buildBidResponse(bid, context); bidResponse.nurl = bid.nurl; if (bid.burl) { bidResponse.burl = bid.burl; } - bidResponse.ad = replaceAuctionPrice(bid.adm, bid.price); + if (bidResponse.mediaType !== NATIVE) { + bidResponse.ad = replaceAuctionPrice(bid.adm, bid.price); + } if (bid.ext && bid.ext.dchain) { deepSetValue(bidResponse, 'meta.dchain', bid.ext.dchain); } @@ -197,35 +206,37 @@ const converter = ortbConverter({ }); export const spec = { - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, NATIVE], gvlid: GVLID, code: BIDDER_CODE, isBidRequestValid: (bidRequest) => { - return !!(bidRequest.sizes && - bidRequest.params && + const hasPublisherAndTag = !!(bidRequest.params && bidRequest.params.publisherId && bidRequest.params.tagId); + if (!hasPublisherAndTag) { + return false; + } + const { hasBanner, hasNative } = getMediaType(bidRequest); + return hasBanner || hasNative; }, buildRequests: (validBidRequests, bidderRequest) => { - const [bidRequest] = validBidRequests; - const auctionId = bidderRequest.auctionId || validBidRequests[0]?.auctionId; - const data = converter.toORTB({ - bidderRequest: bidderRequest, - bidRequests: validBidRequests, - context: { auctionId } + const bannerBids = []; + const nativeBids = []; + + validBidRequests.forEach(bid => { + const { hasBanner, hasNative } = getMediaType(bid); + if (hasBanner) bannerBids.push(bid); + if (hasNative) nativeBids.push(bid); }); - const {publisherId} = bidRequest.params; - const url = END_POINT_URL + '?publisher=' + publisherId; - return { - url, - method: 'POST', - data: data, - bids: validBidRequests, - options: { - withCredentials: false - }, - }; + const requests = []; + if (bannerBids.length) { + requests.push(createTaboolaRequest(bannerBids, bidderRequest, BANNER_ENDPOINT_URL, BANNER)); + } + if (nativeBids.length) { + requests.push(createTaboolaRequest(nativeBids, bidderRequest, NATIVE_ENDPOINT_URL, NATIVE)); + } + return requests; }, interpretResponse: (serverResponse, request) => { if (!request || !request.bids || !request.data) { @@ -242,7 +253,7 @@ export const spec = { return []; } } else { - bids.push(...converter.fromORTB({response: serverResponse.body, request: request.data}).bids); + bids.push(...converter.fromORTB({ response: serverResponse.body, request: request.data }).bids); } if (isArray(serverResponse.body.ext?.igbid)) { serverResponse.body.ext.igbid.forEach((igbid) => { @@ -338,16 +349,38 @@ export const spec = { return syncs; }, onTimeout: (timeoutData) => { - ajax(EVENT_ENDPOINT + '/timeout', null, JSON.stringify(timeoutData), {method: 'POST'}); + ajax(EVENT_ENDPOINT + '/timeout', null, JSON.stringify(timeoutData), { method: 'POST' }); }, onBidderError: ({ error, bidderRequest }) => { - ajax(EVENT_ENDPOINT + '/bidError', null, JSON.stringify({error, bidderRequest}), {method: 'POST'}); + ajax(EVENT_ENDPOINT + '/bidError', null, JSON.stringify({ error, bidderRequest }), { method: 'POST' }); }, }; -function getSiteProperties({publisherId}, refererInfo, ortb2) { - const {getPageUrl, getReferrer} = internal; +function createTaboolaRequest(bidRequests, bidderRequest, endpointUrl, mediaType) { + const [bidRequest] = bidRequests; + const auctionId = bidderRequest.auctionId || bidRequests[0]?.auctionId; + const data = converter.toORTB({ + bidderRequest: bidderRequest, + bidRequests: bidRequests, + context: { auctionId, mediaType } + }); + const { publisherId } = bidRequest.params; + const url = endpointUrl + '?publisher=' + publisherId; + + return { + url, + method: 'POST', + data: data, + bids: bidRequests, + options: { + withCredentials: false + }, + }; +} + +function getSiteProperties({ publisherId }, refererInfo, ortb2) { + const { getPageUrl, getReferrer } = internal; return { id: publisherId, name: publisherId, @@ -364,7 +397,7 @@ function getSiteProperties({publisherId}, refererInfo, ortb2) { } function fillTaboolaReqData(bidderRequest, bidRequest, data, context) { - const {refererInfo, gdprConsent = {}, uspConsent} = bidderRequest; + const { refererInfo, gdprConsent = {}, uspConsent } = bidderRequest; const site = getSiteProperties(bidRequest.params, refererInfo, bidderRequest.ortb2); const ortb2Device = bidderRequest?.ortb2?.device || {}; @@ -431,14 +464,16 @@ function fillTaboolaReqData(bidderRequest, bidRequest, data, context) { } } -function fillTaboolaImpData(bid, imp) { - const {tagId, position} = bid.params; - imp.banner = getBanners(bid, position); +function fillTaboolaImpData(bid, imp, context) { + const { tagId, position } = bid.params; + if (imp.banner && position) { + imp.banner.pos = position; + } imp.tagid = tagId; - if (typeof bid.getFloor === 'function') { const floorInfo = bid.getFloor({ currency: CURRENCY, + mediaType: context.mediaType, size: '*' }); if (isPlainObject(floorInfo) && floorInfo.currency === CURRENCY && !isNaN(parseFloat(floorInfo.floor))) { @@ -446,7 +481,7 @@ function fillTaboolaImpData(bid, imp) { imp.bidfloorcur = CURRENCY; } } else { - const {bidfloor = null, bidfloorcur = CURRENCY} = bid.params; + const { bidfloor = null, bidfloorcur = CURRENCY } = bid.params; imp.bidfloor = bidfloor; imp.bidfloorcur = bidfloorcur; } @@ -476,22 +511,14 @@ function fillTaboolaImpData(bid, imp) { } } -function getBanners(bid, pos) { +function getMediaType(bidRequest) { + const hasBanner = !!bidRequest?.mediaTypes?.banner?.sizes; + const hasNative = !!bidRequest?.mediaTypes?.native; return { - ...getSizes(bid.sizes), - pos: pos - } -} - -function getSizes(sizes) { - return { - format: sizes.map(size => { - return { - w: size[0], - h: size[1] - } - }) - } + hasBanner, + hasNative, + mediaType: hasNative && !hasBanner ? NATIVE : BANNER + }; } registerBidder(spec); diff --git a/modules/taboolaIdSystem.js b/modules/taboolaIdSystem.js index a370af9752f..64b989e7159 100644 --- a/modules/taboolaIdSystem.js +++ b/modules/taboolaIdSystem.js @@ -4,12 +4,12 @@ * @requires module:modules/userId */ -import {submodule} from '../src/hook.js'; -import {ajax} from '../src/ajax.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {logError} from '../src/utils.js'; -import {gdprDataHandler, gppDataHandler, uspDataHandler} from '../src/adapterManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { ajax } from '../src/ajax.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { logError } from '../src/utils.js'; +import { gdprDataHandler, gppDataHandler, uspDataHandler } from '../src/adapterManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * The Taboola sync endpoint. @@ -46,7 +46,7 @@ const userData = { }, getFromLocalStorage() { - const {hasLocalStorage, localStorageIsEnabled, getDataFromLocalStorage} = sm; + const { hasLocalStorage, localStorageIsEnabled, getDataFromLocalStorage } = sm; if (hasLocalStorage() && localStorageIsEnabled()) { return getDataFromLocalStorage(STORAGE_KEY); } @@ -54,7 +54,7 @@ const userData = { }, getFromCookie() { - const {cookiesAreEnabled, getCookie} = sm; + const { cookiesAreEnabled, getCookie } = sm; if (cookiesAreEnabled()) { const mainCookieData = getCookie(COOKIE_KEY); if (mainCookieData) { @@ -168,7 +168,7 @@ function saveUserIdInLocalStorage(id) { function callTaboolaUserSync(submoduleConfig, currentId, callback) { const skipSync = submoduleConfig?.params?.shouldSkipSync ?? true; if (skipSync) { - callback(currentId ? {taboolaId: currentId} : undefined); + callback(currentId ? { taboolaId: currentId } : undefined); return; } const syncUrl = buildTaboolaSyncUrl(); @@ -180,21 +180,21 @@ function callTaboolaUserSync(submoduleConfig, currentId, callback) { const data = JSON.parse(response); if (data && data.user && data.user.id) { saveUserIdInLocalStorage(data.user.id); - callback(data.user.id ? {taboolaId: data.user.id} : undefined); + callback(data.user.id ? { taboolaId: data.user.id } : undefined); return; } } catch (err) { logError('Taboola user-sync: error parsing JSON response', err); } - callback(currentId ? {taboolaId: currentId} : undefined); + callback(currentId ? { taboolaId: currentId } : undefined); }, error: (err) => { logError('Taboola user-sync: network/endpoint error', err); - callback(currentId ? {taboolaId: currentId} : undefined); + callback(currentId ? { taboolaId: currentId } : undefined); } }, undefined, - {method: 'GET', withCredentials: true} + { method: 'GET', withCredentials: true } ); } diff --git a/modules/tadvertisingBidAdapter.js b/modules/tadvertisingBidAdapter.js index 2db4076f57f..f2bc9af4fe5 100644 --- a/modules/tadvertisingBidAdapter.js +++ b/modules/tadvertisingBidAdapter.js @@ -10,11 +10,11 @@ import { isPlainObject, isInteger } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from "../src/mediaTypes.js"; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {ajax, sendBeacon} from "../src/ajax.js"; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from "../src/mediaTypes.js"; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { ajax, sendBeacon } from "../src/ajax.js"; const BIDDER_CODE = 'tadvertising'; const GVL_ID = 213; @@ -185,7 +185,7 @@ export const spec = { }, buildRequests: function (validBidRequests, bidderRequest) { - let data = converter.toORTB({validBidRequests, bidderRequest}) + let data = converter.toORTB({ validBidRequests, bidderRequest }) deepSetValue(data, 'site.publisher.id', bidderRequest.bids[0].params.publisherId) const bidFloor = getBidFloor(bidderRequest.bids[0]) @@ -215,7 +215,7 @@ export const spec = { } deepSetValue(response, 'body.seatbid.0.bid.0.impid', deepAccess(serverRequest, 'data.imp.0.id')) - const bids = converter.fromORTB({response: response.body, request: serverRequest.data}).bids; + const bids = converter.fromORTB({ response: response.body, request: serverRequest.data }).bids; bids.forEach(bid => { bid.ttl = BID_TTL; @@ -270,7 +270,7 @@ export const spec = { sendNotification(spec.notify_url, 'timeout', payload) }, - onBidderError: function ({error, bidderRequest}) { + onBidderError: function ({ error, bidderRequest }) { const payload = buildErrorNotification(bidderRequest, error) sendNotification(spec.notify_url, 'error', payload) } diff --git a/modules/tagorasBidAdapter.js b/modules/tagorasBidAdapter.js index 6ce54a5a895..4e8132de3ff 100644 --- a/modules/tagorasBidAdapter.js +++ b/modules/tagorasBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { createBuildRequestsFn, createInterpretResponseFn, @@ -11,7 +11,7 @@ import { const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'tagoras'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.tagoras.io`; diff --git a/modules/talkadsBidAdapter.js b/modules/talkadsBidAdapter.js index 60be578ed6e..15376d83731 100644 --- a/modules/talkadsBidAdapter.js +++ b/modules/talkadsBidAdapter.js @@ -1,7 +1,7 @@ import { registerBidder } from '../src/adapters/bidderFactory.js'; import { NATIVE, BANNER } from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; const CURRENCY = 'EUR'; @@ -9,7 +9,7 @@ const BIDDER_CODE = 'talkads'; export const spec = { code: BIDDER_CODE, - supportedMediaTypes: [ NATIVE, BANNER ], + supportedMediaTypes: [NATIVE, BANNER], /** * Determines whether or not the given bid request is valid. diff --git a/modules/tappxBidAdapter.js b/modules/tappxBidAdapter.js index 6ca3adb4d54..869222a6614 100644 --- a/modules/tappxBidAdapter.js +++ b/modules/tappxBidAdapter.js @@ -1,6 +1,6 @@ 'use strict'; -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { logWarn, deepAccess, isFn, isPlainObject, isBoolean, isNumber, isStr, isArray } from '../src/utils.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER, VIDEO } from '../src/mediaTypes.js'; @@ -330,7 +330,7 @@ function buildOneRequest(validBidRequests, bidderRequest) { banner.api = api; - const formatArr = bannerMediaType.sizes.map(size => ({w: size[0], h: size[1]})) + const formatArr = bannerMediaType.sizes.map(size => ({ w: size[0], h: size[1] })) banner.format = Object.assign({}, formatArr); imp.banner = banner; @@ -622,7 +622,7 @@ export function _checkParamDataType(key, value, datatype) { export function _extractPageUrl(validBidRequests, bidderRequest) { const url = bidderRequest?.refererInfo?.page || bidderRequest?.refererInfo?.topmostLocation; - return parseDomain(url, {noLeadingWww: true}); + return parseDomain(url, { noLeadingWww: true }); } registerBidder(spec); diff --git a/modules/targetVideoAdServerVideo.js b/modules/targetVideoAdServerVideo.js index b38da6c9d2b..8b5bccfb7b9 100644 --- a/modules/targetVideoAdServerVideo.js +++ b/modules/targetVideoAdServerVideo.js @@ -38,9 +38,9 @@ export function buildVideoUrl(options) { const iu = options.params.iu; if (isURL.test(iu)) { - const urlComponents = parseUrl(iu, {noDecodeWholeURL: true}); + const urlComponents = parseUrl(iu, { noDecodeWholeURL: true }); - for (const [key, value] of Object.entries({...allTargetingData, ...bid.adserverTargeting, ...defaultParameters})) { + for (const [key, value] of Object.entries({ ...allTargetingData, ...bid.adserverTargeting, ...defaultParameters })) { if (!urlComponents.search.hasOwnProperty(key)) { urlComponents.search[key] = value; } diff --git a/modules/targetVideoBidAdapter.js b/modules/targetVideoBidAdapter.js index 84730231543..e2ddad17ac6 100644 --- a/modules/targetVideoBidAdapter.js +++ b/modules/targetVideoBidAdapter.js @@ -1,14 +1,30 @@ -import {_each, deepAccess, getDefinedParams, parseGPTSingleSizeArrayToRtbSize} from '../src/utils.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {formatRequest, getRtbBid, getSiteObj, getSyncResponse, videoBid, bannerBid, createVideoTag} from '../libraries/targetVideoUtils/bidderUtils.js'; -import {SOURCE, GVLID, BIDDER_CODE, VIDEO_PARAMS, BANNER_ENDPOINT_URL, VIDEO_ENDPOINT_URL, MARGIN, TIME_TO_LIVE} from '../libraries/targetVideoUtils/constants.js'; +import { _each, deepAccess, getDefinedParams, isFn, isPlainObject, parseGPTSingleSizeArrayToRtbSize } from '../src/utils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { formatRequest, getRtbBid, getSiteObj, getSyncResponse, videoBid, bannerBid, createVideoTag } from '../libraries/targetVideoUtils/bidderUtils.js'; +import { SOURCE, GVLID, BIDDER_CODE, VIDEO_PARAMS, BANNER_ENDPOINT_URL, VIDEO_ENDPOINT_URL, MARGIN, TIME_TO_LIVE } from '../libraries/targetVideoUtils/constants.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid */ +function getBidFloor(bid) { + if (!isFn(bid.getFloor)) { + return (bid.params.floor) ? bid.params.floor : null; + } + + const floor = bid.getFloor({ + currency: 'EUR', + mediaType: '*', + size: '*' + }); + if (isPlainObject(floor) && !isNaN(floor.floor) && floor.currency === 'EUR') { + return floor.floor; + } + return null; +} + export const spec = { code: BIDDER_CODE, @@ -38,13 +54,15 @@ export const spec = { version: '$prebid.version$' }; - for (let {params, bidId, sizes, mediaTypes, ...bid} of bidRequests) { + for (let { bidId, sizes, mediaTypes, ...bid } of bidRequests) { for (const mediaType in mediaTypes) { switch (mediaType) { case VIDEO: { + const params = bid.params; const video = mediaTypes[VIDEO]; const placementId = params.placementId; const site = getSiteObj(); + const floor = getBidFloor(bid); if (sizes && !Array.isArray(sizes[0])) sizes = [sizes]; @@ -71,6 +89,12 @@ export const spec = { video: getDefinedParams(video, VIDEO_PARAMS) } + const bidFloor = typeof floor === 'string' ? Number(floor.trim()) + : typeof floor === 'number' ? floor + : NaN; + + if (Number.isFinite(bidFloor) && bidFloor > 0) imp.bidfloor = bidFloor; + if (video.playerSize) { imp.video = Object.assign( imp.video, parseGPTSingleSizeArrayToRtbSize(video.playerSize[0]) || {} @@ -120,7 +144,7 @@ export const spec = { }; } - const {ortb2} = bid; + const { ortb2 } = bid; if (ortb2?.source?.tid) { if (!payload.source) { diff --git a/modules/targetVideoBidAdapter.md b/modules/targetVideoBidAdapter.md index a34ad0aff27..9a204a86991 100644 --- a/modules/targetVideoBidAdapter.md +++ b/modules/targetVideoBidAdapter.md @@ -43,6 +43,7 @@ var adUnits = [ bidder: 'targetVideo', params: { placementId: 12345, + floor: 2, reserve: 0, } }] diff --git a/modules/tcfControl.ts b/modules/tcfControl.ts index 81d5df3d802..d49e34e31a8 100644 --- a/modules/tcfControl.ts +++ b/modules/tcfControl.ts @@ -2,12 +2,12 @@ * This module gives publishers extra set of features to enforce individual purposes of TCF v2 */ -import {deepAccess, logError, logWarn} from '../src/utils.js'; -import {config} from '../src/config.js'; -import adapterManager, {gdprDataHandler} from '../src/adapterManager.js'; +import { deepAccess, logError, logWarn } from '../src/utils.js'; +import { config } from '../src/config.js'; +import adapterManager, { gdprDataHandler } from '../src/adapterManager.js'; import * as events from '../src/events.js'; -import {EVENTS} from '../src/constants.js'; -import {GDPR_GVLIDS, VENDORLESS_GVLID} from '../src/consentHandler.js'; +import { EVENTS } from '../src/constants.js'; +import { GDPR_GVLIDS, VENDORLESS_GVLID } from '../src/consentHandler.js'; import { MODULE_TYPE_ANALYTICS, MODULE_TYPE_BIDDER, @@ -20,7 +20,7 @@ import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE } from '../src/activities/params.js'; -import {registerActivityControl} from '../src/activities/rules.js'; +import { registerActivityControl } from '../src/activities/rules.js'; import { ACTIVITY_ACCESS_DEVICE, ACTIVITY_ACCESS_REQUEST_CREDENTIALS, @@ -33,7 +33,7 @@ import { ACTIVITY_TRANSMIT_PRECISE_GEO, ACTIVITY_TRANSMIT_UFPD } from '../src/activities/activities.js'; -import {processRequestOptions} from '../src/ajax.js'; +import { processRequestOptions } from '../src/ajax.js'; export const STRICT_STORAGE_ENFORCEMENT = 'strictStorageEnforcement'; @@ -149,7 +149,7 @@ export function getGvlid(moduleType, moduleName, fallbackFn) { } else if (moduleType === MODULE_TYPE_PREBID) { return VENDORLESS_GVLID; } else { - let {gvlid, modules} = GDPR_GVLIDS.get(moduleName); + let { gvlid, modules } = GDPR_GVLIDS.get(moduleName); if (gvlid == null && Object.keys(modules).length > 0) { // this behavior is for backwards compatibility; if multiple modules with the same // name declare different GVL IDs, pick the bidder's first, then userId, then analytics @@ -238,7 +238,7 @@ export function validateRules(rule, consentData, currentModule, gvlId, params = } const vendorConsentRequred = rule.enforceVendor && !((gvlId === VENDORLESS_GVLID || (rule.softVendorExceptions || []).includes(currentModule))); const deferS2Sbidders = params['isS2S'] && rule.purpose === 'basicAds' && rule.deferS2Sbidders && !gvlId; - const {purpose, vendor} = getConsent(consentData, ruleOptions.type, ruleOptions.id, gvlId); + const { purpose, vendor } = getConsent(consentData, ruleOptions.type, ruleOptions.id, gvlId); return (!rule.enforcePurpose || purpose) && (!vendorConsentRequred || deferS2Sbidders || vendor); } @@ -252,7 +252,7 @@ function gdprRule(purposeNo, checkConsent, blocked = null, gvlidFallback: any = const allow = !!checkConsent(consentData, modName, gvlid, params); if (!allow) { blocked && blocked.add(modName); - return {allow}; + return { allow }; } } }; @@ -297,7 +297,7 @@ export const transmitEidsRule = exceptPrebidModules((() => { if (ACTIVE_RULES.purpose[pno]?.vendorExceptions?.includes(modName)) { return true; } - const {purpose, vendor} = getConsent(consentData, 'purpose', pno, gvlId); + const { purpose, vendor } = getConsent(consentData, 'purpose', pno, gvlId); if (purpose && (vendor || ACTIVE_RULES.purpose[pno]?.softVendorExceptions?.includes(modName))) { return true; } @@ -433,7 +433,7 @@ export function checkIfCredentialsAllowed(next, options: { withCredentials?: boo const consentData = gdprDataHandler.getConsentData(); const rule = ACTIVE_RULES.purpose[1]; const ruleOptions = CONFIGURABLE_RULES[rule.purpose]; - const {purpose} = getConsent(consentData, ruleOptions.type, ruleOptions.id, null); + const { purpose } = getConsent(consentData, ruleOptions.type, ruleOptions.id, null); if (!purpose && rule.enforcePurpose) { options.withCredentials = false; @@ -444,7 +444,7 @@ export function checkIfCredentialsAllowed(next, options: { withCredentials?: boo export function uninstall() { while (RULE_HANDLES.length) RULE_HANDLES.pop()(); - processRequestOptions.getHooks({hook: checkIfCredentialsAllowed}).remove(); + processRequestOptions.getHooks({ hook: checkIfCredentialsAllowed }).remove(); hooksAdded = false; } diff --git a/modules/teadsBidAdapter.js b/modules/teadsBidAdapter.js index dbdda501658..168990f84c0 100644 --- a/modules/teadsBidAdapter.js +++ b/modules/teadsBidAdapter.js @@ -1,10 +1,10 @@ -import {logError, parseSizesInput, isArray, getBidIdParameter, getWinDimensions, getScreenOrientation} from '../src/utils.js'; -import {getDevicePixelRatio} from '../libraries/devicePixelRatio/devicePixelRatio.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {isAutoplayEnabled} from '../libraries/autoplayDetection/autoplay.js'; -import {getHLen} from '../libraries/navigatorData/navigatorData.js'; -import {getTimeToFirstByte} from '../libraries/timeToFirstBytesUtils/timeToFirstBytesUtils.js'; +import { logError, parseSizesInput, isArray, getBidIdParameter, getWinDimensions, getScreenOrientation } from '../src/utils.js'; +import { getDevicePixelRatio } from '../libraries/devicePixelRatio/devicePixelRatio.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { isAutoplayEnabled } from '../libraries/autoplayDetection/autoplay.js'; +import { getHLen } from '../libraries/navigatorData/navigatorData.js'; +import { getTimeToFirstByte } from '../libraries/timeToFirstBytesUtils/timeToFirstBytesUtils.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; /** @@ -25,7 +25,7 @@ const gdprStatus = { const FP_TEADS_ID_COOKIE_NAME = '_tfpvi'; const OB_USER_TOKEN_KEY = 'OB-USER-TOKEN'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -346,14 +346,14 @@ function getFirstPartyTeadsIdParameter(validBidRequests) { const firstPartyTeadsIdFromUserIdModule = validBidRequests?.[0]?.userIdAsEids?.find(eid => eid.source === 'teads.com')?.uids?.[0].id; if (firstPartyTeadsIdFromUserIdModule) { - return {firstPartyCookieTeadsId: firstPartyTeadsIdFromUserIdModule}; + return { firstPartyCookieTeadsId: firstPartyTeadsIdFromUserIdModule }; } if (storage.cookiesAreEnabled(null)) { const firstPartyTeadsIdFromCookie = storage.getCookie(FP_TEADS_ID_COOKIE_NAME, null); if (firstPartyTeadsIdFromCookie) { - return {firstPartyCookieTeadsId: firstPartyTeadsIdFromCookie}; + return { firstPartyCookieTeadsId: firstPartyTeadsIdFromCookie }; } } diff --git a/modules/teadsIdSystem.js b/modules/teadsIdSystem.js index 9c9b07cf355..b7703630116 100644 --- a/modules/teadsIdSystem.js +++ b/modules/teadsIdSystem.js @@ -5,11 +5,11 @@ * @requires module:modules/userId */ -import {isStr, isNumber, logError, logInfo, isEmpty, timestamp} from '../src/utils.js' -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { isStr, isNumber, logError, logInfo, isEmpty, timestamp } from '../src/utils.js' +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -35,7 +35,7 @@ export const gdprReason = { GDPR_APPLIES_PUBLISHER_CLASSIC: 120, }; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** @type {Submodule} */ export const teadsIdSubmodule = { @@ -56,7 +56,7 @@ export const teadsIdSubmodule = { * @returns {{teadsId:string}} */ decode(value) { - return {teadsId: value} + return { teadsId: value } }, /** * performs action to obtain id and return a value in the callback's response argument @@ -92,9 +92,9 @@ export const teadsIdSubmodule = { } }; - ajax(url, callbacks, undefined, {method: 'GET'}); + ajax(url, callbacks, undefined, { method: 'GET' }); }; - return {callback: resp}; + return { callback: resp }; }, eids: { teadsId: { diff --git a/modules/tealBidAdapter.js b/modules/tealBidAdapter.js index 4374646b102..0cac4b7c243 100644 --- a/modules/tealBidAdapter.js +++ b/modules/tealBidAdapter.js @@ -1,8 +1,8 @@ -import {deepSetValue, deepAccess, triggerPixel, deepClone, isEmpty, logError, shuffle} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' -import {BANNER} from '../src/mediaTypes.js'; -import {pbsExtensions} from '../libraries/pbsExtensions/pbsExtensions.js' +import { deepSetValue, deepAccess, triggerPixel, deepClone, isEmpty, logError, shuffle } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js' const BIDDER_CODE = 'teal'; const GVLID = 1378; const DEFAULT_ENDPOINT = 'https://a.bids.ws/openrtb2/auction'; @@ -43,7 +43,7 @@ const converter = ortbConverter({ export const spec = { code: BIDDER_CODE, gvlid: GVLID, - supportedMediaTypes: [BANNER], + supportedMediaTypes: [BANNER, NATIVE, VIDEO], aliases: [], isBidRequestValid: function(bid) { @@ -52,7 +52,7 @@ export const spec = { buildRequests: function(bidRequests, bidderRequest) { const { bidder } = bidRequests[0]; - const data = converter.toORTB({bidRequests, bidderRequest}); + const data = converter.toORTB({ bidRequests, bidderRequest }); const account = deepAccess(bidRequests[0], 'params.account', null); const subAccount = deepAccess(bidRequests[0], 'params.subAccount', null); deepSetValue(data, 'site.publisher.id', account); @@ -79,10 +79,10 @@ export const spec = { Object.entries(modifiers).forEach(([field, combineFn]) => { const obj = resp.ext?.[field]; if (!isEmpty(obj)) { - resp.ext[field] = {[bidder]: combineFn(Object.values(obj))}; + resp.ext[field] = { [bidder]: combineFn(Object.values(obj)) }; } }); - const bids = converter.fromORTB({response: resp, request: request.data}).bids; + const bids = converter.fromORTB({ response: resp, request: request.data }).bids; return bids; }, diff --git a/modules/teqBlazeSalesAgentBidAdapter.js b/modules/teqBlazeSalesAgentBidAdapter.js new file mode 100644 index 00000000000..f2cbf2d57db --- /dev/null +++ b/modules/teqBlazeSalesAgentBidAdapter.js @@ -0,0 +1,41 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { + buildPlacementProcessingFunction, + buildRequestsBase, + interpretResponse, + isBidRequestValid +} from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'teqBlazeSalesAgent'; +const AD_URL = 'https://be-agent.teqblaze.io/pbjs'; + +const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => { + const aeeSignals = bidderRequest.ortb2?.site?.ext?.data?.scope3_aee; + + if (aeeSignals) { + placement.axei = aeeSignals.include; + placement.axex = aeeSignals.exclude; + + if (aeeSignals.macro) { + placement.axem = aeeSignals.macro; + } + } +}; + +const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement }); + +const buildRequests = (validBidRequests = [], bidderRequest = {}) => { + return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction }); +}; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(['placementId']), + buildRequests, + interpretResponse +}; + +registerBidder(spec); diff --git a/modules/teqBlazeSalesAgentBidAdapter.md b/modules/teqBlazeSalesAgentBidAdapter.md new file mode 100644 index 00000000000..d0c1475643d --- /dev/null +++ b/modules/teqBlazeSalesAgentBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: TeqBlaze Sales Agent Bidder Adapter +Module Type: TeqBlaze Sales Agent Bidder Adapter +Maintainer: support@teqblaze.com +``` + +# Description + +Connects to TeqBlaze Sales Agent for bids. +TeqBlaze Sales Agent bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'teqBlazeSalesAgent', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'teqBlazeSalesAgent', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'teqBlazeSalesAgent', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` diff --git a/modules/terceptAnalyticsAdapter.js b/modules/terceptAnalyticsAdapter.js index 6bc86ba8c98..4d4cdf6ff4e 100644 --- a/modules/terceptAnalyticsAdapter.js +++ b/modules/terceptAnalyticsAdapter.js @@ -28,7 +28,7 @@ var terceptAnalyticsAdapter = Object.assign(adapter( if (eventType === EVENTS.BID_TIMEOUT) { args.forEach(item => { mapBidResponse(item, 'timeout'); }); } else if (eventType === EVENTS.AUCTION_INIT) { - Object.assign(events, {bids: []}); + Object.assign(events, { bids: [] }); events.auctionInit = args; auctionTimestamp = args.timestamp; adUnitMap.set(args.auctionId, args.adUnits); diff --git a/modules/theAdxBidAdapter.js b/modules/theAdxBidAdapter.js index d57e307c7e1..2d4343b329e 100644 --- a/modules/theAdxBidAdapter.js +++ b/modules/theAdxBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { logInfo, isEmpty, deepAccess, parseUrl, parseSizesInput, _map } from '../src/utils.js'; import { BANNER, diff --git a/modules/tncIdSystem.js b/modules/tncIdSystem.js index 44fb7a1182f..fafbb9d1700 100644 --- a/modules/tncIdSystem.js +++ b/modules/tncIdSystem.js @@ -26,7 +26,7 @@ const TNC_PREBIDJS_PROVIDER_ID = 'c8549079-f149-4529-a34b-3fa91ef257d1'; const TNC_LOCAL_VALUE_KEY = 'tncid'; let moduleConfig = null; -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); function fixURL(config, ns) { config.params = (config && config.params) ? config.params : {}; diff --git a/modules/topLevelPaapi.js b/modules/topLevelPaapi.js index 3fb613ff728..60eb99f8588 100644 --- a/modules/topLevelPaapi.js +++ b/modules/topLevelPaapi.js @@ -1,12 +1,12 @@ -import {submodule} from '../src/hook.js'; -import {config} from '../src/config.js'; -import {logError, logInfo, logWarn, mergeDeep} from '../src/utils.js'; -import {auctionStore} from '../libraries/weakStore/weakStore.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {emit} from '../src/events.js'; -import {BID_STATUS, EVENTS} from '../src/constants.js'; -import {PbPromise} from '../src/utils/promise.js'; -import {getBidToRender, getRenderingData, markWinningBid} from '../src/adRendering.js'; +import { submodule } from '../src/hook.js'; +import { config } from '../src/config.js'; +import { logError, logInfo, logWarn, mergeDeep } from '../src/utils.js'; +import { auctionStore } from '../libraries/weakStore/weakStore.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { emit } from '../src/events.js'; +import { BID_STATUS, EVENTS } from '../src/constants.js'; +import { PbPromise } from '../src/utils/promise.js'; +import { getBidToRender, getRenderingData, markWinningBid } from '../src/adRendering.js'; let getPAAPIConfig, expandFilters, moduleConfig; @@ -20,9 +20,9 @@ config.getConfig('paapi', (cfg) => { getRenderingData.before(getRenderingDataHook); markWinningBid.before(markWinningBidHook); } else { - getBidToRender.getHooks({hook: renderPaapiHook}).remove(); - getRenderingData.getHooks({hook: getRenderingDataHook}).remove(); - markWinningBid.getHooks({hook: markWinningBidHook}).remove(); + getBidToRender.getHooks({ hook: renderPaapiHook }).remove(); + getRenderingData.getHooks({ hook: getRenderingDataHook }).remove(); + markWinningBid.getHooks({ hook: markWinningBidHook }).remove(); } }); @@ -59,7 +59,7 @@ function renderPaapiHook(next, adId, forRender = true, cb) { }) .then((bid) => { if (bid == null || isPaapiBid(bid) || bid?.status === BID_STATUS.RENDERED) return bid; - return getPAAPIBids({adUnitCode: bid.adUnitCode}).then(res => { + return getPAAPIBids({ adUnitCode: bid.adUnitCode }).then(res => { const paapiBid = bidIfRenderable(res[bid.adUnitCode]); if (paapiBid) { if (!forRender) return paapiBid; @@ -110,7 +110,7 @@ function onAuctionConfig(auctionId, auctionConfigs) { Object.entries(auctionConfigs).forEach(([adUnitCode, auctionConfig]) => { mergeDeep(auctionConfig, base); if (moduleConfig.autorun ?? true) { - getPAAPIBids({adUnitCode, auctionId}); + getPAAPIBids({ adUnitCode, auctionId }); } }); } @@ -156,7 +156,7 @@ export function getPAAPIBids(filters, raa = (...args) => navigator.runAdAuction( .map(([adUnitCode, auctionId]) => { const bids = paapiBids(auctionId); if (bids && !bids.hasOwnProperty(adUnitCode)) { - const auctionConfig = getPAAPIConfig({adUnitCode, auctionId})[adUnitCode]; + const auctionConfig = getPAAPIConfig({ adUnitCode, auctionId })[adUnitCode]; if (auctionConfig) { emit(EVENTS.RUN_PAAPI_AUCTION, { auctionId, @@ -179,12 +179,12 @@ export function getPAAPIBids(filters, raa = (...args) => navigator.runAdAuction( emit(EVENTS.PAAPI_BID, bid); return bid; } else { - emit(EVENTS.PAAPI_NO_BID, {auctionId, adUnitCode, auctionConfig}); + emit(EVENTS.PAAPI_NO_BID, { auctionId, adUnitCode, auctionConfig }); return null; } }).catch(error => { logError(MODULE_NAME, `error (auction "${auctionId}", adUnit "${adUnitCode}"):`, error); - emit(EVENTS.PAAPI_ERROR, {auctionId, adUnitCode, error, auctionConfig}); + emit(EVENTS.PAAPI_ERROR, { auctionId, adUnitCode, error, auctionConfig }); return null; }); } diff --git a/modules/topicsFpdModule.js b/modules/topicsFpdModule.js index 49abc7a5aa3..364294d2837 100644 --- a/modules/topicsFpdModule.js +++ b/modules/topicsFpdModule.js @@ -1,14 +1,14 @@ -import {isEmpty, logError, logWarn, mergeDeep, safeJSONParse} from '../src/utils.js'; -import {getRefererInfo} from '../src/refererDetection.js'; -import {submodule} from '../src/hook.js'; -import {PbPromise} from '../src/utils/promise.js'; -import {config} from '../src/config.js'; -import {getCoreStorageManager} from '../src/storageManager.js'; +import { isEmpty, logError, logWarn, mergeDeep, safeJSONParse } from '../src/utils.js'; +import { getRefererInfo } from '../src/refererDetection.js'; +import { submodule } from '../src/hook.js'; +import { PbPromise } from '../src/utils/promise.js'; +import { config } from '../src/config.js'; +import { getCoreStorageManager } from '../src/storageManager.js'; -import {isActivityAllowed} from '../src/activities/rules.js'; -import {ACTIVITY_ENRICH_UFPD} from '../src/activities/activities.js'; -import {activityParams} from '../src/activities/activityParams.js'; -import {MODULE_TYPE_BIDDER} from '../src/activities/modules.js'; +import { isActivityAllowed } from '../src/activities/rules.js'; +import { ACTIVITY_ENRICH_UFPD } from '../src/activities/activities.js'; +import { activityParams } from '../src/activities/activityParams.js'; +import { MODULE_TYPE_BIDDER } from '../src/activities/modules.js'; const MODULE_NAME = 'topicsFpd'; const DEFAULT_EXPIRATION_DAYS = 21; @@ -72,7 +72,7 @@ export function getTopicsData(name, topics, taxonomies = TAXONOMIES) { segtax: taxonomies[taxonomyVersion], segclass: modelVersion }, - segment: topics.map((topic) => ({id: topic.topic.toString()})) + segment: topics.map((topic) => ({ id: topic.topic.toString() })) }; if (name != null) { datum.name = name; @@ -106,7 +106,7 @@ export function getTopics(doc = document) { const topicsData = getTopics().then((topics) => getTopicsData(getRefererInfo().domain, topics)); -export function processFpd(config, {global}, {data = topicsData} = {}) { +export function processFpd(config, { global }, { data = topicsData } = {}) { if (!LOAD_TOPICS_INITIALISE) { loadTopicsForBidders(); LOAD_TOPICS_INITIALISE = true; @@ -120,7 +120,7 @@ export function processFpd(config, {global}, {data = topicsData} = {}) { } }); } - return {global}; + return { global }; }); } @@ -134,7 +134,7 @@ export function getCachedTopics() { const storedSegments = new Map(safeJSONParse(coreStorage.getDataFromLocalStorage(topicStorageName))); storedSegments && storedSegments.forEach((value, cachedBidder) => { // Check bidder exist in config for cached bidder data and then only retrieve the cached data - const bidderConfigObj = bidderList.find(({bidder}) => cachedBidder === bidder) + const bidderConfigObj = bidderList.find(({ bidder }) => cachedBidder === bidder) if (bidderConfigObj && isActivityAllowed(ACTIVITY_ENRICH_UFPD, activityParams(MODULE_TYPE_BIDDER, cachedBidder))) { if (!isCachedDataExpired(value[lastUpdated], bidderConfigObj?.expiry || DEFAULT_EXPIRATION_DAYS)) { Object.keys(value).forEach((segData) => { @@ -159,7 +159,7 @@ export function receiveMessage(evt) { try { const data = safeJSONParse(evt.data); if (getLoadedIframeURL().includes(evt.origin) && data && data.segment && !isEmpty(data.segment.topics)) { - const {domain, topics, bidder} = data.segment; + const { domain, topics, bidder } = data.segment; const iframeTopicsData = getTopicsData(domain, topics); iframeTopicsData && storeInLocalStorage(bidder, iframeTopicsData); } @@ -241,13 +241,13 @@ export function loadTopicsForBidders(doc = document) { const bidderLsEntry = storedSegments.get(bidder); if (!bidderLsEntry || (bidderLsEntry && isCachedDataExpired(bidderLsEntry[lastUpdated], fetchRate || DEFAULT_FETCH_RATE_IN_DAYS))) { - window.fetch(`${fetchUrl}?bidder=${bidder}`, {browsingTopics: true}) + window.fetch(`${fetchUrl}?bidder=${bidder}`, { browsingTopics: true }) .then(response => { return response.json(); }) .then(data => { if (data && data.segment && !isEmpty(data.segment.topics)) { - const {domain, topics, bidder} = data.segment; + const { domain, topics, bidder } = data.segment; const fetchTopicsData = getTopicsData(domain, topics); fetchTopicsData && storeInLocalStorage(bidder, fetchTopicsData); } diff --git a/modules/tpmnBidAdapter.js b/modules/tpmnBidAdapter.js index 270a9fb3fdd..6e80e56a542 100644 --- a/modules/tpmnBidAdapter.js +++ b/modules/tpmnBidAdapter.js @@ -23,7 +23,7 @@ const COMMON_PARAMS = [ export const VIDEO_RENDERER_URL = 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js'; export const ADAPTER_VERSION = '2.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, supportedMediaTypes: SUPPORTED_AD_TYPES, @@ -142,7 +142,7 @@ const CONVERTER = ortbConverter({ return imp; }, bidResponse(buildBidResponse, bid, context) { - const {bidRequest} = context; + const { bidRequest } = context; const bidResponse = buildBidResponse(bid, context); if (bidResponse.mediaType === BANNER) { bidResponse.ad = bid.adm; @@ -160,7 +160,7 @@ const CONVERTER = ortbConverter({ let videoParams = bidRequest.mediaTypes[VIDEO]; if (videoParams) { videoParams = Object.assign({}, videoParams, bidRequest.params.video); - bidRequest = {...bidRequest, mediaTypes: {[VIDEO]: videoParams}} + bidRequest = { ...bidRequest, mediaTypes: { [VIDEO]: videoParams } } } orig(imp, bidRequest, context); }, diff --git a/modules/trafficgateBidAdapter.js b/modules/trafficgateBidAdapter.js index 47cf3e052ca..ab6db9c878d 100644 --- a/modules/trafficgateBidAdapter.js +++ b/modules/trafficgateBidAdapter.js @@ -1,7 +1,7 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {deepAccess, mergeDeep} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { deepAccess, mergeDeep } from '../src/utils.js'; const BIDDER_CODE = 'trafficgate'; const URL = 'https://[HOST].bc-plugin.com/prebidjs' @@ -64,7 +64,7 @@ const converter = ortbConverter({ imp: { bidfloor(setBidFloor, imp, bidRequest, context) { const floor = {}; - setBidFloor(floor, bidRequest, {...context, currency: 'USD'}); + setBidFloor(floor, bidRequest, { ...context, currency: 'USD' }); if (floor.bidfloorcur === 'USD') { Object.assign(imp, floor); } @@ -74,7 +74,7 @@ const converter = ortbConverter({ let videoParams = bidRequest.mediaTypes[VIDEO]; if (videoParams) { videoParams = Object.assign({}, videoParams, bidRequest.params.video); - bidRequest = {...bidRequest, mediaTypes: {[VIDEO]: videoParams}} + bidRequest = { ...bidRequest, mediaTypes: { [VIDEO]: videoParams } } } orig(imp, bidRequest, context); if (imp.video && videoParams?.context === 'outstream') { @@ -111,7 +111,7 @@ function createRequest(bidRequests, bidderRequest, mediaType) { return { method: 'POST', url: URL.replace('[HOST]', bidRequests[0].params.host), - data: converter.toORTB({bidRequests, bidderRequest, context: {mediaType}}) + data: converter.toORTB({ bidRequests, bidderRequest, context: { mediaType } }) } } @@ -125,9 +125,9 @@ function isBannerBid(bid) { function interpretResponse(resp, req) { if (!resp.body) { - resp.body = {nbr: 0}; + resp.body = { nbr: 0 }; } - return converter.fromORTB({request: req.data, response: resp.body}); + return converter.fromORTB({ request: req.data, response: resp.body }); } export const spec2 = { diff --git a/modules/trionBidAdapter.js b/modules/trionBidAdapter.js index 4af2eb6a549..87c4fb65f62 100644 --- a/modules/trionBidAdapter.js +++ b/modules/trionBidAdapter.js @@ -1,14 +1,14 @@ -import {getBidIdParameter, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { getBidIdParameter, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { getStorageManager } from '../src/storageManager.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; -import {isWebdriverEnabled} from '../libraries/webdriver/webdriver.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; +import { isWebdriverEnabled } from '../libraries/webdriver/webdriver.js'; const BID_REQUEST_BASE_URL = 'https://in-appadvertising.com/api/bidRequest'; const USER_SYNC_URL = 'https://in-appadvertising.com/api/userSync.html'; const BIDDER_CODE = 'trion'; const BASE_KEY = '_trion_'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -55,7 +55,7 @@ export const spec = { bid.currency = result.currency; bid.netRevenue = result.netRevenue; if (result.adomain) { - bid.meta = {advertiserDomains: result.adomain}; + bid.meta = { advertiserDomains: result.adomain }; } bidResponses.push(bid); } diff --git a/modules/tripleliftBidAdapter.js b/modules/tripleliftBidAdapter.js index 503edaa8864..4cbe600df92 100644 --- a/modules/tripleliftBidAdapter.js +++ b/modules/tripleliftBidAdapter.js @@ -4,7 +4,7 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { registerBidder } from '../src/adapters/bidderFactory.js'; import { config } from '../src/config.js'; import { getStorageManager } from '../src/storageManager.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; const GVLID = 28; const BIDDER_CODE = 'triplelift'; @@ -13,7 +13,7 @@ const BANNER_TIME_TO_LIVE = 300; const VIDEO_TIME_TO_LIVE = 3600; let gdprApplies = null; let consentString = null; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const tripleliftAdapterSpec = { gvlid: GVLID, @@ -79,7 +79,7 @@ export const tripleliftAdapterSpec = { }; }, - interpretResponse: function(serverResponse, {bidderRequest}) { + interpretResponse: function(serverResponse, { bidderRequest }) { let bids = serverResponse.body.bids || []; const paapi = serverResponse.body.paapi || []; diff --git a/modules/trustxBidAdapter.js b/modules/trustxBidAdapter.js index 2b0f2c80331..cd4f549c819 100644 --- a/modules/trustxBidAdapter.js +++ b/modules/trustxBidAdapter.js @@ -6,11 +6,11 @@ import { deepSetValue, mergeDeep } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js'; -import {config} from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { config } from '../src/config.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -44,7 +44,7 @@ const ortbAdapterConverter = ortbConverter({ const floorInfo = bidRequest.getFloor({ currency: SUPPORTED_CURRENCY, mediaType: curMediaType, - size: bidRequest.sizes ? bidRequest.sizes.map(([w, h]) => ({w, h})) : '*' + size: bidRequest.sizes ? bidRequest.sizes.map(([w, h]) => ({ w, h })) : '*' }); if (floorInfo && typeof floorInfo === 'object' && @@ -146,7 +146,7 @@ const ortbAdapterConverter = ortbConverter({ return requestObj; }, bidResponse(buildBidResponse, bid, context) { - const {bidRequest} = context; + const { bidRequest } = context; let responseMediaType; if (bid.mtype === 2) { @@ -219,7 +219,7 @@ export const spec = { const requestData = ortbAdapterConverter.toORTB({ bidRequests: validBidRequests, bidderRequest, - context: {contextMediaType: adType} + context: { contextMediaType: adType } }); if (validBidRequests[0].params.test) { diff --git a/modules/ttdBidAdapter.js b/modules/ttdBidAdapter.js index 4598c3b8a7a..1da498cbe06 100644 --- a/modules/ttdBidAdapter.js +++ b/modules/ttdBidAdapter.js @@ -21,6 +21,7 @@ const BIDDER_CODE_LONG = 'thetradedesk'; const BIDDER_ENDPOINT = 'https://direct.adsrvr.org/bid/bidder/'; const BIDDER_ENDPOINT_HTTP2 = 'https://d2.adsrvr.org/bid/bidder/'; const USER_SYNC_ENDPOINT = 'https://match.adsrvr.org'; +const TTL = 360; const MEDIA_TYPE = { BANNER: 1, @@ -143,6 +144,8 @@ function getImpression(bidRequest) { }; const gpid = utils.deepAccess(bidRequest, 'ortb2Imp.ext.gpid'); + const exp = TTL; + impression.exp = exp; const tagid = gpid || bidRequest.params.placementId; if (tagid) { impression.tagid = tagid; @@ -170,7 +173,7 @@ function getImpression(bidRequest) { const secure = utils.deepAccess(bidRequest, 'ortb2Imp.secure'); impression.secure = isNumber(secure) ? secure : 1 - const {video: _, ...ortb2ImpWithoutVideo} = bidRequest.ortb2Imp; // if enabled, video is already assigned above + const { video: _, ...ortb2ImpWithoutVideo } = bidRequest.ortb2Imp; // if enabled, video is already assigned above utils.mergeDeep(impression, ortb2ImpWithoutVideo) return impression; @@ -477,7 +480,7 @@ export const spec = { dealId: bid.dealid || null, currency: currency || 'USD', netRevenue: true, - ttl: bid.ttl || 360, + ttl: bid.ttl || TTL, meta: {}, }; diff --git a/modules/twistDigitalBidAdapter.js b/modules/twistDigitalBidAdapter.js index bed9e531a26..373ac79c26a 100644 --- a/modules/twistDigitalBidAdapter.js +++ b/modules/twistDigitalBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { isBidRequestValid, createInterpretResponseFn, createUserSyncGetter, createBuildRequestsFn, onBidWon } from '../libraries/vidazooUtils/bidderUtils.js'; @@ -10,7 +10,7 @@ const DEFAULT_SUB_DOMAIN = 'exchange'; const BIDDER_CODE = 'twistdigital'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { return `https://${subDomain}.twist.win`; diff --git a/modules/ucfunnelAnalyticsAdapter.js b/modules/ucfunnelAnalyticsAdapter.js index 20a412cdfdb..b4df46086bf 100644 --- a/modules/ucfunnelAnalyticsAdapter.js +++ b/modules/ucfunnelAnalyticsAdapter.js @@ -1,9 +1,9 @@ -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; -import {getGlobal} from '../src/prebidGlobal.js'; -import {logError, logInfo, deepClone} from '../src/utils.js'; +import { getGlobal } from '../src/prebidGlobal.js'; +import { logError, logInfo, deepClone } from '../src/utils.js'; const analyticsType = 'endpoint'; @@ -35,7 +35,7 @@ export const parseAdUnitCode = function (bidResponse) { return bidResponse.adUnitCode.toLowerCase(); }; -export const ucfunnelAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER, analyticsType}), { +export const ucfunnelAnalyticsAdapter = Object.assign(adapter({ ANALYTICS_SERVER, analyticsType }), { cachedAuctions: {}, @@ -107,7 +107,7 @@ export const ucfunnelAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER, message.adUnits[adUnitCode][bidder] = bidResponse; }, createBidMessage(auctionEndArgs, winningBids, timeoutBids) { - const {auctionId, timestamp, auctionEnd, adUnitCodes, bidsReceived, noBids} = auctionEndArgs; + const { auctionId, timestamp, auctionEnd, adUnitCodes, bidsReceived, noBids } = auctionEndArgs; const message = this.createCommonMessage(auctionId); message.auctionElapsed = (auctionEnd - timestamp); @@ -161,7 +161,7 @@ export const ucfunnelAnalyticsAdapter = Object.assign(adapter({ANALYTICS_SERVER, handleBidWon(bidWonArgs) { this.sendEventMessage('imp', this.createImpressionMessage(bidWonArgs)); }, - track({eventType, args}) { + track({ eventType, args }) { if (analyticsOptions.sampled) { switch (eventType) { case BID_WON: diff --git a/modules/ucfunnelBidAdapter.js b/modules/ucfunnelBidAdapter.js index f73bd470b14..5b791bf6a25 100644 --- a/modules/ucfunnelBidAdapter.js +++ b/modules/ucfunnelBidAdapter.js @@ -1,7 +1,7 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { generateUUID, _each, deepAccess } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO, NATIVE} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO, NATIVE } from '../src/mediaTypes.js'; import { getStorageManager } from '../src/storageManager.js'; import { config } from '../src/config.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; @@ -20,7 +20,7 @@ const VIDEO_CONTEXT = { INSTREAM: 0, OUSTREAM: 2 } -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const spec = { code: BIDDER_CODE, @@ -233,7 +233,7 @@ function getFloor(bid, size, mediaTypes) { var bidFloor = bid.getFloor({ currency: CURRENCY, mediaType: getMediaType(mediaTypes), - size: (size) ? [ size[0], size[1] ] : '*', + size: (size) ? [size[0], size[1]] : '*', }); if (bidFloor?.currency === CURRENCY) { return bidFloor.floor; diff --git a/modules/uid2IdSystem.js b/modules/uid2IdSystem.js index 0f052fd6e44..e20880332c7 100644 --- a/modules/uid2IdSystem.js +++ b/modules/uid2IdSystem.js @@ -7,11 +7,11 @@ import { logInfo, logWarn } from '../src/utils.js'; import { submodule } from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; import { Uid2GetId, Uid2CodeVersion, extractIdentityFromParams } from '../libraries/uid2IdSystemShared/uid2IdSystem_shared.js'; -import {UID2_EIDS} from '../libraries/uid2Eids/uid2Eids.js'; +import { UID2_EIDS } from '../libraries/uid2Eids/uid2Eids.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -41,7 +41,7 @@ function createLogger(logger, prefix) { const _logInfo = createLogger(logInfo, LOG_PRE_FIX); const _logWarn = createLogger(logWarn, LOG_PRE_FIX); -export const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME}); +export const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); /** @type {Submodule} */ export const uid2IdSubmodule = { diff --git a/modules/underdogmediaBidAdapter.js b/modules/underdogmediaBidAdapter.js index 45bac54e64c..738fb22e312 100644 --- a/modules/underdogmediaBidAdapter.js +++ b/modules/underdogmediaBidAdapter.js @@ -8,11 +8,11 @@ import { logWarn, parseSizesInput } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {isSlotMatchingAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { isSlotMatchingAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { percentInView } from '../libraries/percentInView/percentInView.js'; -import {isIframe} from '../libraries/omsUtils/index.js'; +import { isIframe } from '../libraries/omsUtils/index.js'; const BIDDER_CODE = 'underdogmedia'; const UDM_ADAPTER_VERSION = '7.30V'; diff --git a/modules/undertoneBidAdapter.js b/modules/undertoneBidAdapter.js index badc0911270..fbfd236e91f 100644 --- a/modules/undertoneBidAdapter.js +++ b/modules/undertoneBidAdapter.js @@ -2,11 +2,11 @@ * Adapter to send bids to Undertone */ -import {deepAccess, parseUrl, extractDomainFromHost, getWinDimensions} from '../src/utils.js'; +import { deepAccess, parseUrl, extractDomainFromHost, getWinDimensions } from '../src/utils.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; import { getViewportCoordinates } from '../libraries/viewport/viewport.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; const BIDDER_CODE = 'undertone'; const URL = 'https://hb.undertone.com/hb'; @@ -41,7 +41,7 @@ function getGdprQueryParams(gdprConsent) { function getBannerCoords(id) { const element = document.getElementById(id); if (element) { - const {left, top} = getBoundingClientRect(element); + const { left, top } = getBoundingClientRect(element); const viewport = getViewportCoordinates(); return [Math.round(left + (viewport.left || 0)), Math.round(top + (viewport.top || 0))]; } diff --git a/modules/unicornBidAdapter.js b/modules/unicornBidAdapter.js index 4f0c3e3696d..825bd26be23 100644 --- a/modules/unicornBidAdapter.js +++ b/modules/unicornBidAdapter.js @@ -1,7 +1,7 @@ import { logInfo, deepAccess, generateUUID } from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { getStorageManager } from '../src/storageManager.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -13,7 +13,7 @@ const UNICORN_ENDPOINT = 'https://ds.uncn.jp/pb/0/bid.json'; const UNICORN_DEFAULT_CURRENCY = 'JPY'; const UNICORN_PB_COOKIE_KEY = '__pb_unicorn_aud'; const UNICORN_PB_VERSION = '1.1'; -const storage = getStorageManager({bidderCode: BIDDER_CODE}); +const storage = getStorageManager({ bidderCode: BIDDER_CODE }); /** * Placement ID and Account ID are required. @@ -173,7 +173,7 @@ const getUid = () => { * @param {Array} arr */ const makeFormat = arr => arr.map((s) => { - return {w: s[0], h: s[1]}; + return { w: s[0], h: s[1] }; }); export const spec = { diff --git a/modules/unifiedIdSystem.js b/modules/unifiedIdSystem.js index 0ffe1b5009f..a6335b33b63 100644 --- a/modules/unifiedIdSystem.js +++ b/modules/unifiedIdSystem.js @@ -6,9 +6,9 @@ */ import { logError } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; -import {submodule} from '../src/hook.js' -import {UID1_EIDS} from '../libraries/uid1Eids/uid1Eids.js'; +import { ajax } from '../src/ajax.js'; +import { submodule } from '../src/hook.js' +import { UID1_EIDS } from '../libraries/uid1Eids/uid1Eids.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -71,9 +71,9 @@ export const unifiedIdSubmodule = { callback(); } }; - ajax(url, callbacks, undefined, {method: 'GET', withCredentials: true}); + ajax(url, callbacks, undefined, { method: 'GET', withCredentials: true }); }; - return {callback: resp}; + return { callback: resp }; }, eids: { tdid: { diff --git a/modules/uniquestAnalyticsAdapter.js b/modules/uniquestAnalyticsAdapter.js index fff6abc56b9..608c20cb866 100644 --- a/modules/uniquestAnalyticsAdapter.js +++ b/modules/uniquestAnalyticsAdapter.js @@ -1,8 +1,8 @@ -import {logError} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { logError } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; import adapterManager from '../src/adapterManager.js'; -import {EVENTS} from '../src/constants.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { EVENTS } from '../src/constants.js'; +import { getRefererInfo } from '../src/refererDetection.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; const ADAPTER_CODE = 'uniquest'; @@ -68,7 +68,7 @@ function auctionEndHandler(eventType, args, pageUrl) { } } -const baseAdapter = adapter({analyticsType: 'endpoint'}); +const baseAdapter = adapter({ analyticsType: 'endpoint' }); const uniquestAdapter = Object.assign({}, baseAdapter, { enableAnalytics(config = {}) { @@ -85,7 +85,7 @@ const uniquestAdapter = Object.assign({}, baseAdapter, { baseAdapter.disableAnalytics.apply(this, arguments); }, - track({eventType, args}) { + track({ eventType, args }) { const refererInfo = getRefererInfo(); const pageUrl = refererInfo.page; diff --git a/modules/uniquestBidAdapter.js b/modules/uniquestBidAdapter.js index 7fad6df68f0..d2ba0abf8a2 100644 --- a/modules/uniquestBidAdapter.js +++ b/modules/uniquestBidAdapter.js @@ -1,8 +1,8 @@ -import {getBidIdParameter} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; -import {interpretResponse} from '../libraries/uniquestUtils/uniquestUtils.js'; +import { getBidIdParameter } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; +import { interpretResponse } from '../libraries/uniquestUtils/uniquestUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory').Bid} Bid diff --git a/modules/uniquest_widgetBidAdapter.js b/modules/uniquest_widgetBidAdapter.js index f40c47b238c..a4412919330 100644 --- a/modules/uniquest_widgetBidAdapter.js +++ b/modules/uniquest_widgetBidAdapter.js @@ -1,8 +1,8 @@ -import {getBidIdParameter} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {tryAppendQueryString} from '../libraries/urlUtils/urlUtils.js'; -import {interpretResponse} from '../libraries/uniquestUtils/uniquestUtils.js'; +import { getBidIdParameter } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { tryAppendQueryString } from '../libraries/urlUtils/urlUtils.js'; +import { interpretResponse } from '../libraries/uniquestUtils/uniquestUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory').Bid} Bid diff --git a/modules/unrulyBidAdapter.js b/modules/unrulyBidAdapter.js index 3f9c4dd1253..df0192079e0 100644 --- a/modules/unrulyBidAdapter.js +++ b/modules/unrulyBidAdapter.js @@ -1,7 +1,7 @@ import { deepAccess, logError } from '../src/utils.js'; -import {Renderer} from '../src/Renderer.js' -import {registerBidder} from '../src/adapters/bidderFactory.js' -import {VIDEO, BANNER} from '../src/mediaTypes.js' +import { Renderer } from '../src/Renderer.js' +import { registerBidder } from '../src/adapters/bidderFactory.js' +import { VIDEO, BANNER } from '../src/mediaTypes.js' function configureUniversalTag(exchangeRenderer, requestId) { if (!exchangeRenderer.config) throw new Error('UnrulyBidAdapter: Missing renderer config.'); @@ -56,14 +56,8 @@ const RemoveDuplicateSizes = (validBid) => { } }; -const ConfigureProtectedAudience = (validBid, protectedAudienceEnabled) => { - if (!protectedAudienceEnabled && validBid.ortb2Imp && validBid.ortb2Imp.ext) { - delete validBid.ortb2Imp.ext.ae; - } -} - const getRequests = (conf, validBidRequests, bidderRequest) => { - const {bids, bidderRequestId, bidderCode, ...bidderRequestData} = bidderRequest; + const { bids, bidderRequestId, bidderCode, ...bidderRequestData } = bidderRequest; const invalidBidsCount = bidderRequest.bids.length - validBidRequests.length; const requestBySiteId = {}; @@ -71,7 +65,6 @@ const getRequests = (conf, validBidRequests, bidderRequest) => { const currSiteId = validBid.params.siteId; addBidFloorInfo(validBid); RemoveDuplicateSizes(validBid); - ConfigureProtectedAudience(validBid, conf.protectedAudienceEnabled); requestBySiteId[currSiteId] = requestBySiteId[currSiteId] || []; requestBySiteId[currSiteId].push(validBid); }); @@ -90,7 +83,7 @@ const getRequests = (conf, validBidRequests, bidderRequest) => { ) }; - request.push(Object.assign({}, {data, ...conf})); + request.push(Object.assign({}, { data, ...conf })); }); return request; @@ -226,43 +219,18 @@ export const adapter = { 'options': { 'contentType': 'application/json' }, - 'protectedAudienceEnabled': bidderRequest.paapi?.enabled }, validBidRequests, bidderRequest); }, interpretResponse: function (serverResponse) { - if (!(serverResponse && serverResponse.body && (serverResponse.body.auctionConfigs || serverResponse.body.bids))) { + if (!(serverResponse && serverResponse.body && serverResponse.body.bids)) { return []; } const serverResponseBody = serverResponse.body; - let bids = []; - let fledgeAuctionConfigs = null; - if (serverResponseBody.bids.length) { - bids = handleBidResponseByMediaType(serverResponseBody.bids); - } - - if (serverResponseBody.auctionConfigs) { - const auctionConfigs = serverResponseBody.auctionConfigs; - const bidIdList = Object.keys(auctionConfigs); - if (bidIdList.length) { - bidIdList.forEach((bidId) => { - fledgeAuctionConfigs = [{ - 'bidId': bidId, - 'config': auctionConfigs[bidId] - }]; - }) - } - } + const bids = handleBidResponseByMediaType(serverResponseBody.bids); - if (!fledgeAuctionConfigs) { - return bids; - } - - return { - bids, - paapi: fledgeAuctionConfigs - }; + return bids; } }; diff --git a/modules/userId/eids.js b/modules/userId/eids.js index b35eea2fab8..61a1634f64f 100644 --- a/modules/userId/eids.js +++ b/modules/userId/eids.js @@ -1,4 +1,4 @@ -import {logError, deepClone, isFn, isStr} from '../../src/utils.js'; +import { logError, deepClone, isFn, isStr } from '../../src/utils.js'; export const EID_CONFIG = new Map(); @@ -73,9 +73,9 @@ export function createEidsArray(bidRequestUserId, eidConfigs = EID_CONFIG) { eids = [eids]; } eids.forEach(eid => { - eid.uids = eid.uids.filter(({id}) => isStr(id)) + eid.uids = eid.uids.filter(({ id }) => isStr(id)) }) - eids = eids.filter(({uids}) => uids?.length > 0); + eids = eids.filter(({ uids }) => uids?.length > 0); } catch (e) { logError(`Could not generate EID for "${name}"`, e); } diff --git a/modules/userId/eids.md b/modules/userId/eids.md index f6f62229f53..bdd8a0bb3e8 100644 --- a/modules/userId/eids.md +++ b/modules/userId/eids.md @@ -25,6 +25,14 @@ userIdAsEids = [ }] }, + { + source: 'locid.com', + uids: [{ + id: 'some-random-id-value', + atype: 1 + }] + }, + { source: 'adserver.org', uids: [{ diff --git a/modules/userId/index.ts b/modules/userId/index.ts index 006b0421d7d..4946e96f578 100644 --- a/modules/userId/index.ts +++ b/modules/userId/index.ts @@ -3,13 +3,13 @@ * @module modules/userId */ -import {config} from '../../src/config.js'; +import { config } from '../../src/config.js'; import * as events from '../../src/events.js'; -import {addApiMethod, startAuction, type StartAuctionOptions} from '../../src/prebid.js'; +import { addApiMethod, startAuction, type StartAuctionOptions } from '../../src/prebid.js'; import adapterManager from '../../src/adapterManager.js'; -import {EVENTS} from '../../src/constants.js'; -import {module, ready as hooksReady} from '../../src/hook.js'; -import {EID_CONFIG, getEids} from './eids.js'; +import { EVENTS } from '../../src/constants.js'; +import { module, ready as hooksReady } from '../../src/hook.js'; +import { EID_CONFIG, getEids } from './eids.js'; import { discloseStorageUse, getCoreStorageManager, @@ -33,26 +33,26 @@ import { logInfo, logWarn, mergeDeep } from '../../src/utils.js'; -import {getPPID as coreGetPPID} from '../../src/adserver.js'; -import {defer, delay, PbPromise} from '../../src/utils/promise.js'; -import {newMetrics, timedAuctionHook, useMetrics} from '../../src/utils/perfMetrics.js'; -import {findRootDomain} from '../../src/fpd/rootDomain.js'; -import {allConsent, GDPR_GVLIDS} from '../../src/consentHandler.js'; -import {MODULE_TYPE_UID} from '../../src/activities/modules.js'; -import {isActivityAllowed, registerActivityControl} from '../../src/activities/rules.js'; -import {ACTIVITY_ACCESS_DEVICE, ACTIVITY_ENRICH_EIDS} from '../../src/activities/activities.js'; -import {activityParams} from '../../src/activities/activityParams.js'; -import {USERSYNC_DEFAULT_CONFIG, type UserSyncConfig} from '../../src/userSync.js'; -import type {ORTBRequest} from "../../src/types/ortb/request.d.ts"; -import type {AnyFunction, Wraps} from "../../src/types/functions.d.ts"; -import type {ProviderParams, UserId, UserIdProvider, UserIdConfig, IdProviderSpec, ProviderResponse} from "./spec.ts"; +import { getPPID as coreGetPPID } from '../../src/adserver.js'; +import { defer, delay, PbPromise } from '../../src/utils/promise.js'; +import { newMetrics, timedAuctionHook, useMetrics } from '../../src/utils/perfMetrics.js'; +import { findRootDomain } from '../../src/fpd/rootDomain.js'; +import { allConsent, GDPR_GVLIDS } from '../../src/consentHandler.js'; +import { MODULE_TYPE_UID } from '../../src/activities/modules.js'; +import { isActivityAllowed, registerActivityControl } from '../../src/activities/rules.js'; +import { ACTIVITY_ACCESS_DEVICE, ACTIVITY_ENRICH_EIDS } from '../../src/activities/activities.js'; +import { activityParams } from '../../src/activities/activityParams.js'; +import { USERSYNC_DEFAULT_CONFIG, type UserSyncConfig } from '../../src/userSync.js'; +import type { ORTBRequest } from "../../src/types/ortb/request.d.ts"; +import type { AnyFunction, Wraps } from "../../src/types/functions.d.ts"; +import type { ProviderParams, UserId, UserIdProvider, UserIdConfig, IdProviderSpec, ProviderResponse } from "./spec.ts"; import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE, ACTIVITY_PARAM_STORAGE_TYPE, ACTIVITY_PARAM_STORAGE_WRITE } from '../../src/activities/params.js'; -import {beforeInitAuction} from '../../src/auction.js'; +import { beforeInitAuction } from '../../src/auction.js'; const MODULE_NAME = 'User ID'; const COOKIE = STORAGE_TYPE_COOKIES; @@ -381,8 +381,8 @@ function mkPriorityMaps() { function activeModuleGetter(key, useGlobals, modules) { return function () { - for (const {allowed, bidders, module} of modules) { - if (!dep.isAllowed(ACTIVITY_ENRICH_EIDS, activityParams(MODULE_TYPE_UID, module?.config?.name, {init: false}))) { + for (const { allowed, bidders, module } of modules) { + if (!dep.isAllowed(ACTIVITY_ENRICH_EIDS, activityParams(MODULE_TYPE_UID, module?.config?.name, { init: false }))) { continue; } const value = module.idObj?.[key]; @@ -430,22 +430,22 @@ function mkPriorityMaps() { } }) if (!allNonGlobal) { - global[key] = activeModuleGetter(key, true, modules.map(({bidders, module}) => ({allowed: bidders == null, bidders, module}))); + global[key] = activeModuleGetter(key, true, modules.map(({ bidders, module }) => ({ allowed: bidders == null, bidders, module }))); } bidderFilters.forEach(bidderCode => { bidder[bidderCode] = bidder[bidderCode] ?? {}; - bidder[bidderCode][key] = activeModuleGetter(key, false, modules.map(({bidders, module}) => ({allowed: bidders?.includes(bidderCode), bidders, module}))); + bidder[bidderCode][key] = activeModuleGetter(key, false, modules.map(({ bidders, module }) => ({ allowed: bidders?.includes(bidderCode), bidders, module }))); }) }); const combined = Object.values(bidder).concat([global]).reduce((combo, map) => Object.assign(combo, map), {}); - Object.assign(map, {global, bidder, combined}); + Object.assign(map, { global, bidder, combined }); } return map; } export function enrichEids(ortb2Fragments) { - const {global: globalFpd, bidder: bidderFpd} = ortb2Fragments; - const {global: globalMods, bidder: bidderMods} = initializedSubmodules; + const { global: globalFpd, bidder: bidderFpd } = ortb2Fragments; + const { global: globalMods, bidder: bidderMods } = initializedSubmodules; const globalEids = getEids(globalMods); if (globalEids.length > 0) { deepSetValue(globalFpd, 'user.ext.eids', (globalFpd.user?.ext?.eids ?? []).concat(globalEids)); @@ -469,14 +469,14 @@ declare module '../../src/adapterManager' { } } -export function addIdData({ortb2Fragments}) { - ortb2Fragments = ortb2Fragments ?? {global: {}, bidder: {}} +export function addIdData({ ortb2Fragments }) { + ortb2Fragments = ortb2Fragments ?? { global: {}, bidder: {} } enrichEids(ortb2Fragments); } const INIT_CANCELED = {}; -function idSystemInitializer({mkDelay = delay} = {}) { +function idSystemInitializer({ mkDelay = delay } = {}) { const startInit = defer(); const startCallbacks = defer(); let cancel; @@ -531,7 +531,7 @@ function idSystemInitializer({mkDelay = delay} = {}) { * with `ready` = true, starts initialization; with `refresh` = true, reinitialize submodules (optionally * filtered by `submoduleNames`). */ - return function ({refresh = false, submoduleNames = null, ready = false} = {}) { + return function ({ refresh = false, submoduleNames = null, ready = false } = {}) { if (ready && !initialized) { initialized = true; startInit.resolve(); @@ -593,13 +593,13 @@ function getPPID(eids = getUserIdsAsEids() || []) { * @param {Object} reqBidsConfigObj required; This is the same param that's used in pbjs.requestBids. * @param {function} fn required; The next function in the chain, used by hook.ts */ -export const startAuctionHook = timedAuctionHook('userId', function requestBidsHook(fn, reqBidsConfigObj: StartAuctionOptions, {mkDelay = delay, getIds = getUserIdsAsync} = {}) { +export const startAuctionHook = timedAuctionHook('userId', function requestBidsHook(fn, reqBidsConfigObj: StartAuctionOptions, { mkDelay = delay, getIds = getUserIdsAsync } = {}) { PbPromise.race([ getIds().catch(() => null), mkDelay(auctionDelay) ]).then(() => { addIdData(reqBidsConfigObj); - uidMetrics().join(useMetrics(reqBidsConfigObj.metrics), {propagate: false, includeGroups: true}); + uidMetrics().join(useMetrics(reqBidsConfigObj.metrics), { propagate: false, includeGroups: true }); // calling fn allows prebid to continue processing fn.call(this, reqBidsConfigObj); }); @@ -635,9 +635,9 @@ export function adUnitEidsHook(next, auction) { if (bidderCode == null) return globalEids; if (!eidsByBidder.hasOwnProperty(bidderCode)) { eidsByBidder[bidderCode] = mergeDeep( - {eids: []}, - {eids: globalEids}, - {eids: auction.getFPD()?.bidder?.[bidderCode]?.user?.ext?.eids ?? []} + { eids: [] }, + { eids: globalEids }, + { eids: auction.getFPD()?.bidder?.[bidderCode]?.user?.ext?.eids ?? [] } ).eids; } return eidsByBidder[bidderCode]; @@ -657,7 +657,7 @@ export function adUnitEidsHook(next, auction) { * @returns {boolean} */ function addedStartAuctionHook() { - return !!startAuction.getHooks({hook: startAuctionHook}).length; + return !!startAuction.getHooks({ hook: startAuctionHook }).length; } /** @@ -776,10 +776,10 @@ function retryOnCancel(initParams?) { * submoduleNames submodules to refresh. If omitted, refresh all submodules. * callback called when the refresh is complete */ -function refreshUserIds({submoduleNames}: { +function refreshUserIds({ submoduleNames }: { submoduleNames?: string[] } = {}, callback?: () => void): Promise> { - return retryOnCancel({refresh: true, submoduleNames}) + return retryOnCancel({ refresh: true, submoduleNames }) .then((userIds) => { if (callback && isFn(callback)) { callback(); @@ -1062,10 +1062,10 @@ function updateEIDConfig(submodules) { } export function generateSubmoduleContainers(options, configs, prevSubmodules = submodules, registry = submoduleRegistry) { - const {autoRefresh, retainConfig} = options; + const { autoRefresh, retainConfig } = options; return registry .reduce((acc, submodule) => { - const {name, aliasName} = submodule; + const { name, aliasName } = submodule; const matchesName = (query) => [name, aliasName].some(value => value?.toLowerCase() === query.toLowerCase()); const submoduleConfig = configs.find((configItem) => matchesName(configItem.name)); @@ -1180,7 +1180,7 @@ export function attachIdSystem(submodule: IdProviderSpec) { updateSubmodules(); // TODO: a test case wants this to work even if called after init (the setConfig({userId})) // so we trigger a refresh. But is that even possible outside of tests? - initIdSystem({refresh: true, submoduleNames: [submodule.name]}); + initIdSystem({ refresh: true, submoduleNames: [submodule.name] }); } } @@ -1216,7 +1216,7 @@ const enforceStorageTypeRule = (userIdsConfig, enforceStorageType) => { if (params[ACTIVITY_PARAM_STORAGE_TYPE] !== submoduleConfig.storage.type) { const reason = `${submoduleConfig.name} attempts to store data in ${params[ACTIVITY_PARAM_STORAGE_TYPE]} while configuration allows ${submoduleConfig.storage.type}.`; if (enforceStorageType) { - return {allow: false, reason}; + return { allow: false, reason }; } else { logWarn(reason); } @@ -1229,12 +1229,12 @@ const enforceStorageTypeRule = (userIdsConfig, enforceStorageType) => { * so a callback is added to fire after the consentManagement module. * @param {{getConfig:function}} config */ -export function init(config, {mkDelay = delay} = {}) { +export function init(config, { mkDelay = delay } = {}) { ppidSource = undefined; submodules = []; configRegistry = []; initializedSubmodules = mkPriorityMaps(); - initIdSystem = idSystemInitializer({mkDelay}); + initIdSystem = idSystemInitializer({ mkDelay }); if (configListener != null) { configListener(); } @@ -1248,18 +1248,18 @@ export function init(config, {mkDelay = delay} = {}) { if (userSync) { ppidSource = userSync.ppid; if (userSync.userIds) { - const {autoRefresh = false, retainConfig = true, enforceStorageType} = userSync; + const { autoRefresh = false, retainConfig = true, enforceStorageType } = userSync; configRegistry = userSync.userIds; syncDelay = isNumber(userSync.syncDelay) ? userSync.syncDelay : USERSYNC_DEFAULT_CONFIG.syncDelay auctionDelay = isNumber(userSync.auctionDelay) ? userSync.auctionDelay : USERSYNC_DEFAULT_CONFIG.auctionDelay; - updateSubmodules({retainConfig, autoRefresh}); + updateSubmodules({ retainConfig, autoRefresh }); unregisterEnforceStorageTypeRule?.(); - unregisterEnforceStorageTypeRule = registerActivityControl(ACTIVITY_ACCESS_DEVICE, 'enforceStorageTypeRule', enforceStorageTypeRule(submodules.map(({config}) => config), enforceStorageType)); + unregisterEnforceStorageTypeRule = registerActivityControl(ACTIVITY_ACCESS_DEVICE, 'enforceStorageTypeRule', enforceStorageTypeRule(submodules.map(({ config }) => config), enforceStorageType)); updateIdPriority(userSync.idPriority, submoduleRegistry); - initIdSystem({ready: true}); + initIdSystem({ ready: true }); const submodulesToRefresh = submodules.filter(item => item.refreshIds); if (submodulesToRefresh.length) { - refreshUserIds({submoduleNames: submodulesToRefresh.map(item => item.submodule.name)}); + refreshUserIds({ submoduleNames: submodulesToRefresh.map(item => item.submodule.name) }); } } } @@ -1278,7 +1278,7 @@ export function init(config, {mkDelay = delay} = {}) { } export function resetUserIds() { - config.setConfig({userSync: {}}) + config.setConfig({ userSync: {} }) init(config); } diff --git a/modules/userId/spec.ts b/modules/userId/spec.ts index d3fbae835dd..6bcfaa6b288 100644 --- a/modules/userId/spec.ts +++ b/modules/userId/spec.ts @@ -1,8 +1,8 @@ -import type {BidderCode, StorageDisclosure} from "../../src/types/common"; -import {STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE, type StorageType} from "../../src/storageManager.ts"; -import type {AllConsentData} from "../../src/consentHandler.ts"; -import type {Ext} from '../../src/types/ortb/common'; -import type {ORTBRequest} from "../../src/types/ortb/request"; +import type { BidderCode, StorageDisclosure } from "../../src/types/common"; +import { STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE, type StorageType } from "../../src/storageManager.ts"; +import type { AllConsentData } from "../../src/consentHandler.ts"; +import type { Ext } from '../../src/types/ortb/common'; +import type { ORTBRequest } from "../../src/types/ortb/request"; export type UserIdProvider = string; diff --git a/modules/userId/userId.md b/modules/userId/userId.md index 8ffd8f83043..f7bea8fd9f8 100644 --- a/modules/userId/userId.md +++ b/modules/userId/userId.md @@ -91,6 +91,16 @@ pbjs.setConfig({ name: '_li_pbid', expires: 60 } + }, { + name: 'locId', + params: { + endpoint: 'https://id.example.com/locid' + }, + storage: { + type: 'html5', + name: '_locid', + expires: 7 + } }, { name: 'criteo', storage: { // It is best not to specify this parameter since the module needs to be called as many times as possible diff --git a/modules/validationFpdModule/index.ts b/modules/validationFpdModule/index.ts index 8b68540ed3d..2e964b2f6e7 100644 --- a/modules/validationFpdModule/index.ts +++ b/modules/validationFpdModule/index.ts @@ -2,10 +2,10 @@ * This module sets default values and validates ortb2 first part data * @module modules/firstPartyData */ -import {deepAccess, isEmpty, isNumber, logWarn} from '../../src/utils.js'; -import {ORTB_MAP} from './config.js'; -import {submodule} from '../../src/hook.js'; -import {getCoreStorageManager} from '../../src/storageManager.js'; +import { deepAccess, isEmpty, isNumber, logWarn } from '../../src/utils.js'; +import { ORTB_MAP } from './config.js'; +import { submodule } from '../../src/hook.js'; +import { getCoreStorageManager } from '../../src/storageManager.js'; // TODO: do FPD modules need their own namespace? const STORAGE = getCoreStorageManager('FPDValidation'); @@ -85,7 +85,7 @@ function typeValidation(data, mapping) { */ export function filterArrayData(arr, child, path, parent) { arr = arr.filter((index, i) => { - const check = typeValidation(index, {type: child.type, isArray: child.isArray}); + const check = typeValidation(index, { type: child.type, isArray: child.isArray }); if (check && Array.isArray(index) === Boolean(child.isArray)) { return true; @@ -157,7 +157,7 @@ export function validateFpd(fpd, path = '', parent = '') { }).filter(key => { const mapping = deepAccess(ORTB_MAP, path + key); // let typeBool = false; - const typeBool = (mapping) ? typeValidation(fpd[key], {type: mapping.type, isArray: mapping.isArray}) : true; + const typeBool = (mapping) ? typeValidation(fpd[key], { type: mapping.type, isArray: mapping.isArray }) : true; if (typeBool || !mapping) return key; diff --git a/modules/valuadBidAdapter.js b/modules/valuadBidAdapter.js index 6a32d80b806..ec969ab719d 100644 --- a/modules/valuadBidAdapter.js +++ b/modules/valuadBidAdapter.js @@ -11,7 +11,7 @@ import { import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { config } from '../src/config.js'; import { getBoundingBox, percentInView } from '../libraries/percentInView/percentInView.js'; -import {isIframe} from '../libraries/omsUtils/index.js'; +import { isIframe } from '../libraries/omsUtils/index.js'; const BIDDER_CODE = 'valuad'; const GVL_ID = 1478; @@ -104,7 +104,7 @@ const converter = ortbConverter({ if (!adSize) { adSize = [0, 0]; } - const size = {w: adSize[0], h: adSize[1]}; + const size = { w: adSize[0], h: adSize[1] }; const element = document.getElementById(bid.adUnitCode) || document.getElementById(getGptSlotInfoForAdUnitCode(bid.adUnitCode)?.divId); const viewabilityAmount = _isViewabilityMeasurable(element) ? _getViewability(element, getWindowTop(), size) : 0; @@ -197,7 +197,7 @@ function interpretResponse(response, request) { } // Restore original call, remove logging and safe navigation - const bidResponses = converter.fromORTB({response: response.body, request: request.data}).bids; + const bidResponses = converter.fromORTB({ response: response.body, request: request.data }).bids; return bidResponses; } diff --git a/modules/ventesBidAdapter.js b/modules/ventesBidAdapter.js index f79ed20514a..fa9f1557719 100644 --- a/modules/ventesBidAdapter.js +++ b/modules/ventesBidAdapter.js @@ -1,9 +1,9 @@ -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {isArray, isNumber, isPlainObject, isStr, replaceAuctionPrice} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isArray, isNumber, isPlainObject, isStr, replaceAuctionPrice } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; -import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js'; -import {hasUserInfo} from '../libraries/adrelevantisUtils/bidderUtils.js'; +import { convertCamelToUnderscore } from '../libraries/appnexusUtils/anUtils.js'; +import { hasUserInfo } from '../libraries/adrelevantisUtils/bidderUtils.js'; const BID_METHOD = 'POST'; const BIDDER_URL = 'https://ad.ventesavenues.in/va/ad'; @@ -96,7 +96,8 @@ function createServerRequestFromAdUnits(adUnits, bidRequestId, adUnitContext) { data: generateBidRequestsFromAdUnits(adUnits, bidRequestId, adUnitContext), options: { contentType: 'application/json', - withCredentials: false} + withCredentials: false + } } } diff --git a/modules/verbenBidAdapter.js b/modules/verbenBidAdapter.js new file mode 100644 index 00000000000..867f669e93e --- /dev/null +++ b/modules/verbenBidAdapter.js @@ -0,0 +1,17 @@ +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { isBidRequestValid, buildRequests, interpretResponse } from '../libraries/teqblazeUtils/bidderUtils.js'; + +const BIDDER_CODE = 'verben'; +const AD_URL = 'https://east-node.verben.com/pbjs'; + +export const spec = { + code: BIDDER_CODE, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], + + isBidRequestValid: isBidRequestValid(), + buildRequests: buildRequests(AD_URL), + interpretResponse +}; + +registerBidder(spec); diff --git a/modules/verbenBidAdapter.md b/modules/verbenBidAdapter.md new file mode 100644 index 00000000000..2d0978bc52f --- /dev/null +++ b/modules/verbenBidAdapter.md @@ -0,0 +1,79 @@ +# Overview + +``` +Module Name: Verben Bidder Adapter +Module Type: Verben Bidder Adapter +Maintainer: support_trading@verben.com +``` + +# Description + +Connects to Verben exchange for bids. +Verben bid adapter supports Banner, Video (instream and outstream) and Native. + +# Test Parameters +``` + var adUnits = [ + // Will return static test banner + { + code: 'adunit1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [320, 50] ], + } + }, + bids: [ + { + bidder: 'verben', + params: { + placementId: 'testBanner', + } + } + ] + }, + { + code: 'addunit2', + mediaTypes: { + video: { + playerSize: [ [640, 480] ], + context: 'instream', + minduration: 5, + maxduration: 60, + } + }, + bids: [ + { + bidder: 'verben', + params: { + placementId: 'testVideo', + } + } + ] + }, + { + code: 'addunit3', + mediaTypes: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + }, + bids: [ + { + bidder: 'verben', + params: { + placementId: 'testNative', + } + } + ] + } + ]; +``` diff --git a/modules/viantBidAdapter.js b/modules/viantBidAdapter.js index 7d621726adc..ee1be030ecb 100644 --- a/modules/viantBidAdapter.js +++ b/modules/viantBidAdapter.js @@ -1,8 +1,8 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; import * as utils from '../src/utils.js'; -import {ortbConverter} from '../libraries/ortbConverter/converter.js' -import {deepAccess, getBidIdParameter, logError} from '../src/utils.js'; +import { ortbConverter } from '../libraries/ortbConverter/converter.js' +import { deepAccess, getBidIdParameter, logError } from '../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').Bid} Bid @@ -44,9 +44,9 @@ export const spec = { interpretResponse(response, request) { if (!response.body) { - response.body = {nbr: 0}; + response.body = { nbr: 0 }; } - const bids = converter.fromORTB({request: request.data, response: response.body}).bids; + const bids = converter.fromORTB({ request: request.data, response: response.body }).bids; return bids; }, @@ -80,7 +80,7 @@ function buildRequests(bids, bidderRequest) { } function createRequest(bidRequests, bidderRequest, mediaType) { - const data = converter.toORTB({bidRequests, bidderRequest, context: {mediaType}}); + const data = converter.toORTB({ bidRequests, bidderRequest, context: { mediaType } }); if (bidderRequest.gdprConsent && typeof bidderRequest.gdprConsent.gdprApplies === 'boolean') { if (!data.regs) data.regs = {}; if (!data.regs.ext) data.regs.ext = {}; diff --git a/modules/vibrantmediaBidAdapter.js b/modules/vibrantmediaBidAdapter.js index 65c6eaa51c1..83f8eba34ff 100644 --- a/modules/vibrantmediaBidAdapter.js +++ b/modules/vibrantmediaBidAdapter.js @@ -7,10 +7,10 @@ import { convertOrtbRequestToProprietaryNative } from '../src/native.js'; * Note: Only BANNER and VIDEO are currently supported by the prebid server. */ -import {getWinDimensions, logError, triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from '../src/mediaTypes.js'; -import {OUTSTREAM} from '../src/video.js'; +import { getWinDimensions, logError, triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js'; +import { OUTSTREAM } from '../src/video.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest diff --git a/modules/vidazooBidAdapter.js b/modules/vidazooBidAdapter.js index ed732a4814a..86044aef889 100644 --- a/modules/vidazooBidAdapter.js +++ b/modules/vidazooBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; import { createSessionId, isBidRequestValid, @@ -12,13 +12,13 @@ import { createBuildRequestsFn, createInterpretResponseFn } from '../libraries/vidazooUtils/bidderUtils.js'; -import {OPT_CACHE_KEY, OPT_TIME_KEY} from '../libraries/vidazooUtils/constants.js'; +import { OPT_CACHE_KEY, OPT_TIME_KEY } from '../libraries/vidazooUtils/constants.js'; const GVLID = 744; const DEFAULT_SUB_DOMAIN = 'prebid'; const BIDDER_CODE = 'vidazoo'; const BIDDER_VERSION = '1.0.0'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); export const webSessionId = createSessionId(); export function createDomain(subDomain = DEFAULT_SUB_DOMAIN) { diff --git a/modules/videoModule/adQueue.js b/modules/videoModule/adQueue.js index a98bd742294..8c9ba15ea72 100644 --- a/modules/videoModule/adQueue.js +++ b/modules/videoModule/adQueue.js @@ -12,7 +12,7 @@ export function AdQueueCoordinator(videoCore, pbEvents) { function queueAd(adTagUrl, divId, options = {}) { const queue = storage[divId]; if (queue) { - queue.push({adTagUrl, options}); + queue.push({ adTagUrl, options }); triggerEvent(AUCTION_AD_LOAD_QUEUED, adTagUrl, options); } else { loadAd(divId, adTagUrl, options); diff --git a/modules/videoModule/index.ts b/modules/videoModule/index.ts index 938d95ae1fd..8d2daef5956 100644 --- a/modules/videoModule/index.ts +++ b/modules/videoModule/index.ts @@ -1,8 +1,8 @@ -import {config} from '../../src/config.js'; +import { config } from '../../src/config.js'; import * as events from '../../src/events.js'; -import {logError, logWarn, mergeDeep} from '../../src/utils.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; -import {EVENTS} from '../../src/constants.js'; +import { logError, logWarn, mergeDeep } from '../../src/utils.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; +import { EVENTS } from '../../src/constants.js'; import { AD_ERROR, AD_IMPRESSION, @@ -12,23 +12,23 @@ import { BID_IMPRESSION, videoEvents } from '../../libraries/video/constants/events.js' -import {PLACEMENT} from '../../libraries/video/constants/ortb.js'; -import {videoKey} from '../../libraries/video/constants/constants.js' -import {videoCoreFactory} from './coreVideo.js'; -import {gamSubmoduleFactory} from './gamAdServerSubmodule.js'; -import {videoImpressionVerifierFactory} from './videoImpressionVerifier.js'; -import {AdQueueCoordinator} from './adQueue.js'; -import {getExternalVideoEventName, getExternalVideoEventPayload} from '../../libraries/video/shared/helpers.js' -import {VIDEO} from '../../src/mediaTypes.js'; -import {auctionManager} from '../../src/auctionManager.js'; -import {doRender} from '../../src/adRendering.js'; -import {getHook} from '../../src/hook.js'; -import {type VideoBid} from '../../src/bidfactory.js'; -import type {BidderCode} from "../../src/types/common.d.ts"; -import type {ORTBImp, ORTBRequest} from "../../src/types/ortb/request.d.ts"; -import type {DeepPartial} from "../../src/types/objects.d.ts"; -import type {AdServerVendor} from "../../libraries/video/constants/vendorCodes.ts"; -import type {VideoEvent} from "../../libraries/video/constants/events.ts"; +import { PLACEMENT } from '../../libraries/video/constants/ortb.js'; +import { videoKey } from '../../libraries/video/constants/constants.js' +import { videoCoreFactory } from './coreVideo.js'; +import { gamSubmoduleFactory } from './gamAdServerSubmodule.js'; +import { videoImpressionVerifierFactory } from './videoImpressionVerifier.js'; +import { AdQueueCoordinator } from './adQueue.js'; +import { getExternalVideoEventName, getExternalVideoEventPayload } from '../../libraries/video/shared/helpers.js' +import { VIDEO } from '../../src/mediaTypes.js'; +import { auctionManager } from '../../src/auctionManager.js'; +import { doRender } from '../../src/adRendering.js'; +import { getHook } from '../../src/hook.js'; +import { type VideoBid } from '../../src/bidfactory.js'; +import type { BidderCode } from "../../src/types/common.d.ts"; +import type { ORTBImp, ORTBRequest } from "../../src/types/ortb/request.d.ts"; +import type { DeepPartial } from "../../src/types/objects.d.ts"; +import type { AdServerVendor } from "../../libraries/video/constants/vendorCodes.ts"; +import type { VideoEvent } from "../../libraries/video/constants/events.ts"; const allVideoEvents = Object.keys(videoEvents).map(eventKey => videoEvents[eventKey]); @@ -293,7 +293,7 @@ export function PbVideo(videoCore_, getConfig_, pbGlobal_, requestBids_, pbEvent function getWinningBid(adUnitCode) { const highestCpmBids = pbGlobal.getHighestCpmBids(adUnitCode); if (!highestCpmBids.length) { - pbEvents.emit(getExternalVideoEventName(AUCTION_AD_LOAD_ABORT), getExternalVideoEventPayload(AUCTION_AD_LOAD_ABORT, {adUnitCode})); + pbEvents.emit(getExternalVideoEventName(AUCTION_AD_LOAD_ABORT), getExternalVideoEventPayload(AUCTION_AD_LOAD_ABORT, { adUnitCode })); return; } return highestCpmBids.shift(); diff --git a/modules/videobyteBidAdapter.js b/modules/videobyteBidAdapter.js index e7eb6f8cd23..5e49b71ce7d 100644 --- a/modules/videobyteBidAdapter.js +++ b/modules/videobyteBidAdapter.js @@ -1,6 +1,6 @@ import { logMessage, logError, deepAccess, isFn, isPlainObject, isStr, isNumber, isArray, deepSetValue } from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO} from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -60,7 +60,7 @@ export const spec = { return; } return bidRequests.map(bidRequest => { - const {params} = bidRequest; + const { params } = bidRequest; let pubId = params.pubId; const placementId = params.placementId; const nId = params.nid; @@ -164,7 +164,7 @@ export const spec = { // BUILD REQUESTS: VIDEO function buildRequestData(bidRequest, bidderRequest) { - const {params} = bidRequest; + const { params } = bidRequest; const videoAdUnit = deepAccess(bidRequest, 'mediaTypes.video', {}); const videoBidderParams = deepAccess(bidRequest, 'params.video', {}); @@ -202,7 +202,7 @@ function buildRequestData(bidRequest, bidderRequest) { floorData = bidRequest.getFloor(bidFloorRequest); } else { if (params.bidfloor) { - floorData = {floor: params.bidfloor, currency: params.currency || 'USD'}; + floorData = { floor: params.bidfloor, currency: params.currency || 'USD' }; } } diff --git a/modules/videojsVideoProvider.js b/modules/videojsVideoProvider.js index 8a214f07a91..62cb6a9d730 100644 --- a/modules/videojsVideoProvider.js +++ b/modules/videojsVideoProvider.js @@ -50,7 +50,7 @@ export function VideojsProvider(providerConfig, vjs_, adState_, timeState_, call let player = null; let playerVersion = null; let playerIsSetup = false; - const {playerConfig, divId} = providerConfig; + const { playerConfig, divId } = providerConfig; let isMuted; let previousLastTimePosition = 0; let lastTimePosition = 0; @@ -141,7 +141,7 @@ export function VideojsProvider(providerConfig, vjs_, adState_, timeState_, call // sequence - TODO not yet supported maxextended: -1, boxingallowed: 1, - playbackmethod: [ playBackMethod ], + playbackmethod: [playBackMethod], playbackend: PLAYBACK_END.VIDEO_COMPLETION, // Per ortb 7.4 skip is omitted since neither the player nor ima plugin imposes a skip button, or a skipmin/max }; @@ -614,7 +614,7 @@ export const utils = { return params.adPluginConfig || {}; // TODO: add adPluginConfig to spec }, - getPositionCode: function({left, top, width, height}) { + getPositionCode: function({ left, top, width, height }) { const bottom = getWinDimensions().innerHeight - top - height; const right = getWinDimensions().innerWidth - left - width; diff --git a/modules/videonowBidAdapter.js b/modules/videonowBidAdapter.js index 563f692693a..107f9bd2643 100644 --- a/modules/videonowBidAdapter.js +++ b/modules/videonowBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {_each, getBidIdParameter, getValue, logError, logInfo} from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { _each, getBidIdParameter, getValue, logError, logInfo } from '../src/utils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -18,7 +18,7 @@ export const spec = { code: BIDDER_CODE, url: RTB_URL, - supportedMediaTypes: [ BANNER ], + supportedMediaTypes: [BANNER], /** * Determines whether or not the given bid request is valid. diff --git a/modules/videoreachBidAdapter.js b/modules/videoreachBidAdapter.js index 29c74c0dc6a..8c77988652a 100644 --- a/modules/videoreachBidAdapter.js +++ b/modules/videoreachBidAdapter.js @@ -1,5 +1,5 @@ -import {getBidIdParameter, getValue} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { getBidIdParameter, getValue } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; const BIDDER_CODE = 'videoreach'; const ENDPOINT_URL = 'https://a.videoreach.com/hb/'; diff --git a/modules/vidoomyBidAdapter.js b/modules/vidoomyBidAdapter.js index 92e11a4dece..94aeb2f3798 100644 --- a/modules/vidoomyBidAdapter.js +++ b/modules/vidoomyBidAdapter.js @@ -1,9 +1,9 @@ -import {deepAccess, isPlainObject, logError, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {Renderer} from '../src/Renderer.js'; -import {INSTREAM, OUTSTREAM} from '../src/video.js'; +import { deepAccess, isPlainObject, logError, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { Renderer } from '../src/Renderer.js'; +import { INSTREAM, OUTSTREAM } from '../src/video.js'; const ENDPOINT = `https://d.vidoomy.com/api/rtbserver/prebid/`; const BIDDER_CODE = 'vidoomy'; @@ -87,7 +87,7 @@ function getBidFloor(bid, mediaType, sizes, bidfloor) { let floor = bidfloor; var size = sizes && sizes.length > 0 ? sizes[0] : '*'; if (typeof bid.getFloor === 'function') { - const floorInfo = bid.getFloor({currency: 'USD', mediaType, size}); + const floorInfo = bid.getFloor({ currency: 'USD', mediaType, size }); if (isPlainObject(floorInfo) && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { floor = Math.max(bidfloor, parseFloat(floorInfo.floor)); } diff --git a/modules/viewdeosDXBidAdapter.js b/modules/viewdeosDXBidAdapter.js index 813072a1dbe..6595f9e9a2c 100644 --- a/modules/viewdeosDXBidAdapter.js +++ b/modules/viewdeosDXBidAdapter.js @@ -1,7 +1,7 @@ -import {deepAccess, flatten, isArray, logError, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {VIDEO} from '../src/mediaTypes.js'; -import {Renderer} from '../src/Renderer.js'; +import { deepAccess, flatten, isArray, logError, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { VIDEO } from '../src/mediaTypes.js'; +import { Renderer } from '../src/Renderer.js'; import { getUserSyncsFn, isBidRequestValid, @@ -48,7 +48,7 @@ export const spec = { * @param {BidderRequest} bidderRequest * @return {Bid[]} An array of bids which were nested inside the server */ - interpretResponse: function (serverResponse, {bidderRequest}) { + interpretResponse: function (serverResponse, { bidderRequest }) { serverResponse = serverResponse.body; let bids = []; diff --git a/modules/vistarsBidAdapter.js b/modules/vistarsBidAdapter.js index 07fb10184c7..33ada9c3266 100644 --- a/modules/vistarsBidAdapter.js +++ b/modules/vistarsBidAdapter.js @@ -62,7 +62,7 @@ export const spec = { return []; } - const bids = converter.fromORTB({response: response.body, request: request.data}).bids; + const bids = converter.fromORTB({ response: response.body, request: request.data }).bids; bids.forEach((bid) => { bid.meta = bid.meta || {}; bid.meta.advertiserDomains = bid.meta.advertiserDomains || []; @@ -78,7 +78,7 @@ export const spec = { getUserSyncs: getUserSyncs(SYNC_ENDPOINT), - supportedMediaTypes: [ BANNER, VIDEO ] + supportedMediaTypes: [BANNER, VIDEO] } registerBidder(spec); diff --git a/modules/visxBidAdapter.js b/modules/visxBidAdapter.js index 801c68acc2d..f75fc1fe4ef 100644 --- a/modules/visxBidAdapter.js +++ b/modules/visxBidAdapter.js @@ -1,10 +1,10 @@ -import {deepAccess, logError, mergeDeep, parseSizesInput, sizeTupleToRtbSize, sizesToSizeTuples, triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {config} from '../src/config.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {INSTREAM as VIDEO_INSTREAM} from '../src/video.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getGptSlotInfoForAdUnitCode} from '../libraries/gptUtils/gptUtils.js'; +import { deepAccess, logError, mergeDeep, parseSizesInput, sizeTupleToRtbSize, sizesToSizeTuples, triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { config } from '../src/config.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { INSTREAM as VIDEO_INSTREAM } from '../src/video.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getGptSlotInfoForAdUnitCode } from '../libraries/gptUtils/gptUtils.js'; import { getBidFromResponse } from '../libraries/processResponse/index.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; @@ -35,7 +35,7 @@ const LOG_ERROR_MESS = { videoMissing: 'Bid request videoType property is missing - ' }; const currencyWhiteList = ['EUR', 'USD', 'GBP', 'PLN', 'CHF', 'SEK']; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); const _bidResponseTimeLogged = []; export const spec = { code: BIDDER_CODE, @@ -178,7 +178,7 @@ export const spec = { cur: [currency], source, ...(payloadUser && { user: payloadUser }), - ...(payloadRegs && {regs: payloadRegs}), + ...(payloadRegs && { regs: payloadRegs }), ...(payloadDevice && { device: payloadDevice }), ...(payloadSite && { site: payloadSite }), ...(payloadContent && { content: payloadContent }), diff --git a/modules/voxBidAdapter.js b/modules/voxBidAdapter.js index 8fb6574548c..e7e03172a28 100644 --- a/modules/voxBidAdapter.js +++ b/modules/voxBidAdapter.js @@ -1,8 +1,8 @@ -import {_map, isArray} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { _map, isArray } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { getCurrencyFromBidderRequest } from '../libraries/ortb2Utils/currency.js'; -import {createRenderer, getMediaTypeFromBid, hasVideoMandatoryParams} from '../libraries/hybridVoxUtils/index.js'; +import { createRenderer, getMediaTypeFromBid, hasVideoMandatoryParams } from '../libraries/hybridVoxUtils/index.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -54,8 +54,7 @@ function buildBid(bidData) { mediaType: BANNER, ttl: TTL, content: bidData.content, - meta: { - advertiserDomains: bidData.advertiserDomains || []} + meta: { advertiserDomains: bidData.advertiserDomains || [] } }; if (bidData.placement === 'video') { diff --git a/modules/vrtcalBidAdapter.js b/modules/vrtcalBidAdapter.js index 07dc35525c3..bd0dd9dc243 100644 --- a/modules/vrtcalBidAdapter.js +++ b/modules/vrtcalBidAdapter.js @@ -1,8 +1,8 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import { BANNER } from '../src/mediaTypes.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import { config } from '../src/config.js'; -import {deepAccess, isFn, isPlainObject} from '../src/utils.js'; +import { deepAccess, isFn, isPlainObject } from '../src/utils.js'; const GVLID = 706; const VRTCAL_USER_SYNC_URL_IFRAME = `https://usync.vrtcal.com/i?ssp=1804&synctype=iframe`; @@ -20,7 +20,7 @@ export const spec = { let floor = 0; if (isFn(bid.getFloor)) { - const floorInfo = bid.getFloor({ currency: 'USD', mediaType: 'banner', size: bid.sizes.map(([w, h]) => ({w, h})) }); + const floorInfo = bid.getFloor({ currency: 'USD', mediaType: 'banner', size: bid.sizes.map(([w, h]) => ({ w, h })) }); if (isPlainObject(floorInfo) && floorInfo.currency === 'USD' && !isNaN(parseFloat(floorInfo.floor))) { floor = Math.max(floor, parseFloat(floorInfo.floor)); @@ -104,7 +104,7 @@ export const spec = { params.regs.ext.gpp_sid = bid.ortb2.regs.gpp_sid; } - return {method: 'POST', url: 'https://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804', data: JSON.stringify(params), options: {withCredentials: false, crossOrigin: true}}; + return { method: 'POST', url: 'https://rtb.vrtcal.com/bidder_prebid.vap?ssp=1804', data: JSON.stringify(params), options: { withCredentials: false, crossOrigin: true } }; }); return requests; diff --git a/modules/vuukleBidAdapter.js b/modules/vuukleBidAdapter.js index 6dd5709fe78..371cf002473 100644 --- a/modules/vuukleBidAdapter.js +++ b/modules/vuukleBidAdapter.js @@ -11,7 +11,7 @@ const VENDOR_ID = 1004; export const spec = { code: BIDDER_CODE, gvlid: VENDOR_ID, - supportedMediaTypes: [ BANNER ], + supportedMediaTypes: [BANNER], isBidRequestValid: function(bid) { return true @@ -56,7 +56,7 @@ export const spec = { method: 'GET', url: URL, data: params, - options: {withCredentials: false} + options: { withCredentials: false } } }); diff --git a/modules/waardexBidAdapter.js b/modules/waardexBidAdapter.js index 7846d12af32..138cbd54601 100644 --- a/modules/waardexBidAdapter.js +++ b/modules/waardexBidAdapter.js @@ -1,7 +1,7 @@ -import {deepAccess, getBidIdParameter, isArray, logError} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; +import { deepAccess, getBidIdParameter, isArray, logError } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; const ENDPOINT = `https://hb.justbidit2.xyz:8843/prebid`; const BIDDER_CODE = 'waardex'; @@ -58,13 +58,14 @@ const buildRequests = (validBidRequests, bidderRequest) => { zoneId = +validBidRequests[0].params.zoneId; } - return {method: 'POST', url: `${ENDPOINT}?pubId=${zoneId}`, data: dataToSend}; + return { method: 'POST', url: `${ENDPOINT}?pubId=${zoneId}`, data: dataToSend }; }; const getCommonBidsData = bidderRequest => { const payload = { ua: navigator.userAgent || '', - language: navigator.language && navigator.language.indexOf('-') !== -1 ? navigator.language.split('-')[0] : ''}; + language: navigator.language && navigator.language.indexOf('-') !== -1 ? navigator.language.split('-')[0] : '' + }; if (bidderRequest && bidderRequest.refererInfo) { // TODO: is 'page' the right value here? diff --git a/modules/weboramaRtdProvider.js b/modules/weboramaRtdProvider.js index bf7f7a043f9..ddda05699f5 100644 --- a/modules/weboramaRtdProvider.js +++ b/modules/weboramaRtdProvider.js @@ -188,6 +188,7 @@ class WeboramaRtdProvider { constructor(components) { this.#components = components; } + /** * Initialize module * @function diff --git a/modules/widespaceBidAdapter.js b/modules/widespaceBidAdapter.js index 7a8dec47a28..498cf5ba7ea 100644 --- a/modules/widespaceBidAdapter.js +++ b/modules/widespaceBidAdapter.js @@ -1,7 +1,7 @@ -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {deepClone, parseQueryStringParameters, parseSizesInput} from '../src/utils.js'; -import {getStorageManager} from '../src/storageManager.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { deepClone, parseQueryStringParameters, parseSizesInput } from '../src/utils.js'; +import { getStorageManager } from '../src/storageManager.js'; import { getBoundingClientRect } from '../libraries/boundingClientRect/boundingClientRect.js'; import { getConnectionInfo } from '../libraries/connectionInfo/connectionUtils.js'; @@ -12,7 +12,7 @@ const LS_KEYS = { LC_UID: 'wsLcuid', CUST_DATA: 'wsCustomData' }; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); let preReqTime = 0; @@ -98,7 +98,7 @@ export const spec = { // GDPR Consent info if (data.gdprCmp) { - const {gdprApplies, consentString, vendorData} = bidderRequest.gdprConsent; + const { gdprApplies, consentString, vendorData } = bidderRequest.gdprConsent; const hasGlobalScope = vendorData && vendorData.hasGlobalScope; data.gdprApplies = gdprApplies ? 1 : gdprApplies === undefined ? '' : 0; data.gdprConsentData = consentString; @@ -162,7 +162,7 @@ export const spec = { userSyncs = serverResponses.reduce((allSyncPixels, response) => { if (response && response.body && response.body[0]) { (response.body[0].syncPixels || []).forEach((url) => { - allSyncPixels.push({type: 'image', url}); + allSyncPixels.push({ type: 'image', url }); }); } return allSyncPixels; diff --git a/modules/winrBidAdapter.js b/modules/winrBidAdapter.js index ee90307eb89..1d5cd60da70 100644 --- a/modules/winrBidAdapter.js +++ b/modules/winrBidAdapter.js @@ -7,15 +7,15 @@ import { isPlainObject, logError } from '../src/utils.js'; -import {config} from '../src/config.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; -import {getANKeywordParam} from '../libraries/appnexusUtils/anKeywords.js'; -import {convertCamelToUnderscore} from '../libraries/appnexusUtils/anUtils.js'; +import { config } from '../src/config.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; +import { getANKeywordParam } from '../libraries/appnexusUtils/anKeywords.js'; +import { convertCamelToUnderscore } from '../libraries/appnexusUtils/anUtils.js'; import { transformSizes } from '../libraries/sizeUtils/tranformSize.js'; -import {addUserId, hasUserInfo, hasAppDeviceInfo, hasAppId, getBidFloor} from '../libraries/adrelevantisUtils/bidderUtils.js'; +import { addUserId, hasUserInfo, hasAppDeviceInfo, hasAppId, getBidFloor } from '../libraries/adrelevantisUtils/bidderUtils.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -31,7 +31,7 @@ const SOURCE = 'pbjs'; const DEFAULT_CURRENCY = 'USD'; const GATE_COOKIE_NAME = 'wnr_gate'; -export const storage = getStorageManager({bidderCode: BIDDER_CODE}); +export const storage = getStorageManager({ bidderCode: BIDDER_CODE }); function buildBid(bidData) { const bid = bidData; diff --git a/modules/wipesBidAdapter.js b/modules/wipesBidAdapter.js index 56a4aeecd71..3a53638c908 100644 --- a/modules/wipesBidAdapter.js +++ b/modules/wipesBidAdapter.js @@ -1,6 +1,6 @@ -import {logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const BIDDER_CODE = 'wipes'; const ALIAS_BIDDER_CODE = ['wi']; diff --git a/modules/wurflRtdProvider.md b/modules/wurflRtdProvider.md index 30651a6ddea..4bc088303e0 100644 --- a/modules/wurflRtdProvider.md +++ b/modules/wurflRtdProvider.md @@ -8,10 +8,11 @@ ## Description -The WURFL RTD module enriches the OpenRTB 2.0 device data with [WURFL data](https://www.scientiamobile.com/wurfl-js-business-edition-at-the-intersection-of-javascript-and-enterprise/). -The module sets the WURFL data in `device.ext.wurfl` and all the bidder adapters will always receive the low entry capabilities like `is_mobile`, `complete_device_name` and `form_factor`, and the `wurfl_id`. +The WURFL RTD module enriches Prebid.js bid requests with comprehensive device detection data. -For a more detailed analysis bidders can subscribe to detect iPhone and iPad models and receive additional [WURFL device capabilities](https://www.scientiamobile.com/capabilities/?products%5B%5D=wurfl-js). +The WURFL RTD module relies on localStorage caching and local client-side detection, providing instant device enrichment on every page load. + +The module enriches `ortb2.device` with complete device information and adds extended WURFL capabilities to `device.ext.wurfl`, ensuring all bidder adapters have immediate access to enriched device data. **Note:** This module loads a dynamically generated JavaScript from prebid.wurflcloud.com @@ -34,10 +35,8 @@ Use `setConfig` to instruct Prebid.js to initilize the WURFL RTD module, as spec This module is configured as part of the `realTimeData.dataProviders` ```javascript -var TIMEOUT = 1000; pbjs.setConfig({ realTimeData: { - auctionDelay: TIMEOUT, dataProviders: [ { name: "wurfl", @@ -49,16 +48,14 @@ pbjs.setConfig({ ### Parameters -| Name | Type | Description | Default | -| :------------------ | :------ | :--------------------------------------------------------------- | :------------- | -| name | String | Real time data module name | Always 'wurfl' | -| waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (optional) | `false` | -| params | Object | | | -| params.altHost | String | Alternate host to connect to WURFL.js | | -| params.abTest | Boolean | Enable A/B testing mode | `false` | -| params.abName | String | A/B test name identifier | `'unknown'` | -| params.abSplit | Number | Fraction of users in treatment group (0-1) | `0.5` | -| params.abExcludeLCE | Boolean | Don't apply A/B testing to LCE bids | `true` | +| Name | Type | Description | Default | +| :------------- | :------ | :----------------------------------------- | :------------- | +| name | String | Real time data module name | Always 'wurfl' | +| params | Object | | | +| params.altHost | String | Alternate host to connect to WURFL.js | | +| params.abTest | Boolean | Enable A/B testing mode | `false` | +| params.abName | String | A/B test name identifier | `'unknown'` | +| params.abSplit | Number | Fraction of users in treatment group (0-1) | `0.5` | ### A/B Testing @@ -67,15 +64,13 @@ The WURFL RTD module supports A/B testing to measure the impact of WURFL enrichm ```javascript pbjs.setConfig({ realTimeData: { - auctionDelay: 1000, dataProviders: [ { name: "wurfl", - waitForIt: true, params: { abTest: true, - abName: "pub_test_sept23", - abSplit: 0.5, // 50% treatment, 50% control + abName: "pub_test", + abSplit: 0.75, // 75% treatment, 25% control }, }, ], diff --git a/modules/xeBidAdapter.js b/modules/xeBidAdapter.js index 9bd6f8adbac..8589a851c8b 100644 --- a/modules/xeBidAdapter.js +++ b/modules/xeBidAdapter.js @@ -1,6 +1,6 @@ -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {buildRequests, getUserSyncs, interpretResponse, isBidRequestValid} from '../libraries/xeUtils/bidderUtils.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { buildRequests, getUserSyncs, interpretResponse, isBidRequestValid } from '../libraries/xeUtils/bidderUtils.js'; const BIDDER_CODE = 'xe'; const ENDPOINT = 'https://pbjs.xe.works/bid'; diff --git a/modules/yahooAdsBidAdapter.js b/modules/yahooAdsBidAdapter.js index b2b92c6ba95..45f6726633c 100644 --- a/modules/yahooAdsBidAdapter.js +++ b/modules/yahooAdsBidAdapter.js @@ -3,7 +3,7 @@ import { BANNER, VIDEO } from '../src/mediaTypes.js'; import { deepAccess, isFn, isStr, isNumber, isArray, isEmpty, isPlainObject, generateUUID, logInfo, logWarn } from '../src/utils.js'; import { config } from '../src/config.js'; import { Renderer } from '../src/Renderer.js'; -import {hasPurpose1Consent} from '../src/utils/gdpr.js'; +import { hasPurpose1Consent } from '../src/utils/gdpr.js'; const INTEGRATION_METHOD = 'prebid.js'; const BIDDER_CODE = 'yahooAds'; @@ -71,7 +71,7 @@ function getSize(size) { function transformSizes(sizes) { if (isArray(sizes) && sizes.length === 2 && !isArray(sizes[0])) { - return [ getSize(sizes) ]; + return [getSize(sizes)]; } return sizes.map(getSize); } @@ -288,6 +288,7 @@ function generateOpenRtbObject(bidderRequest, bid) { } }, source: { + tid: bidderRequest.ortb2?.source?.tid, ext: { hb: 1, adapterver: ADAPTER_VERSION, @@ -505,7 +506,7 @@ function appendFirstPartyData(outBoundBidRequest, bid) { return outBoundBidRequest; }; -function generateServerRequest({payload, requestOptions, bidderRequest}) { +function generateServerRequest({ payload, requestOptions, bidderRequest }) { const pubIdMode = getPubIdMode(bidderRequest); const overrideEndpoint = getConfigValue(bidderRequest, 'endpoint'); let sspEndpoint = overrideEndpoint || SSP_ENDPOINT_DCN_POS; @@ -612,13 +613,13 @@ export const spec = { filteredBidRequests.forEach(bid => { appendImpObject(bid, payload); }); - return [generateServerRequest({payload, requestOptions, bidderRequest})]; + return [generateServerRequest({ payload, requestOptions, bidderRequest })]; } return filteredBidRequests.map(bid => { const payloadClone = generateOpenRtbObject(bidderRequest, bid); appendImpObject(bid, payloadClone); - return generateServerRequest({payload: payloadClone, requestOptions, bidderRequest: bid}); + return generateServerRequest({ payload: payloadClone, requestOptions, bidderRequest: bid }); }); }, diff --git a/modules/yahooAdsBidAdapter.md b/modules/yahooAdsBidAdapter.md index df9b71b2314..a26d24338c5 100644 --- a/modules/yahooAdsBidAdapter.md +++ b/modules/yahooAdsBidAdapter.md @@ -18,6 +18,7 @@ The Yahoo Advertising Bid Adapter is an OpenRTB interface that consolidates all * User ID Modules - ConnectId and others * First Party Data (ortb2 & ortb2Imp) * Custom TTL (time to live) +* Transaction ID (TID) support via ortb2.source.tid # Adapter Aliases Whilst the primary bidder code for this bid adapter is `yahooAds`, the aliases `yahoossp` and `yahooAdvertising` can be used to enable this adapter. If you wish to set Prebid configuration specifically for this bid adapter, then the configuration key _must_ match the used bidder code. All examples in this documentation use the primiry bidder code, but switching `yahooAds` with one of the relevant aliases may be required for your setup. Let's take [setting the request mode](#adapter-request-mode) as an example; if you used the `yahoossp` alias, then the corresponding `setConfig` API call would look like this: @@ -562,6 +563,40 @@ const adUnits = [{ ] ``` +## Transaction ID (TID) Support +The Yahoo Advertising bid adapter supports reading publisher-provided transaction IDs from `ortb2.source.tid` and including them in the OpenRTB request. This enables better bid request tracking and deduplication across the supply chain. + +**Important:** To use transaction IDs, you must enable TIDs in your Prebid configuration by setting `enableTIDs: true`. + +### Global Transaction ID (applies to all bidders) +```javascript +pbjs.setConfig({ + enableTIDs: true, // Required for TID support + ortb2: { + source: { + tid: "transaction-id-12345" + } + } +}); +``` + +### Bidder-Specific Transaction ID (Yahoo Ads only) +```javascript +pbjs.setBidderConfig({ + bidders: ['yahooAds'], + config: { + enableTIDs: true, // Required for TID support + ortb2: { + source: { + tid: "yahoo-specific-tid-67890" + } + } + } +}); +``` + +**Note:** If `enableTIDs` is not set to `true`, the transaction ID will not be available to the adapter, even if `ortb2.source.tid` is configured. When TID is not provided or not enabled, the adapter will not include the `source.tid` field in the OpenRTB request. + # Optional: Bidder bidOverride Parameters The Yahoo Advertising bid adapter allows passing override data to the outbound bid-request that overrides First Party Data. **Important!** We highly recommend using prebid modules to pass data instead of bidder speicifc overrides. diff --git a/modules/yaleoBidAdapter.md b/modules/yaleoBidAdapter.md new file mode 100644 index 00000000000..505d3617fd5 --- /dev/null +++ b/modules/yaleoBidAdapter.md @@ -0,0 +1,39 @@ +# Yaleo Bid Adapter + +# Overview + +``` +Module name: Yaleo Bid Adapter +Module Type: Bidder Adapter +Maintainer: alexandr.kim@audienzz.com +``` + +# Description + +Module that connects to Yaleo's demand sources. + +**Note:** the bid adapter requires correct setup and approval. For more information visit [yaleo.com](https://www.yaleo.com) or contact [hola@yaleo.com](mailto:hola@yaleo.com). + +# Test parameters + +**Note:** to receive bids when testing without proper integration with the demand source, enable Prebid.js debug mode. See [how to enable debug mode](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#debugging) for details. + +```js +const adUnits = [ + { + code: "test-div-1", + mediaTypes: { + banner: { + sizes: [[300, 300], [300, 600]], + } + }, + bids: [{ + bidder: "yaleo", + params: { + placementId: "95a09f24-afb8-441c-977b-08b4039cb88e", + } + }] + } +]; +``` + diff --git a/modules/yaleoBidAdapter.ts b/modules/yaleoBidAdapter.ts new file mode 100755 index 00000000000..980d5634df7 --- /dev/null +++ b/modules/yaleoBidAdapter.ts @@ -0,0 +1,80 @@ +import { ortbConverter } from '../libraries/ortbConverter/converter.js'; +import { pbsExtensions } from '../libraries/pbsExtensions/pbsExtensions.js'; +import { BidderSpec, registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; + +interface YaleoBidParams { + /** + * Yaleo placement ID. + */ + placementId: string; + /** + * Member ID. + * @default 3927 + */ + memberId?: number; + /** + * Maximum CPM value. Bids with a CPM higher than the specified value will be rejected. + */ + maxCpm?: number; +} + +declare module '../src/adUnits' { + interface BidderParams { + [BIDDER_CODE]: YaleoBidParams; + } +} + +const BIDDER_CODE = 'yaleo'; +const AUDIENZZ_VENDOR_ID = 783; +const PREBID_URL = 'https://bidder.yaleo.com/prebid'; +const DEFAULT_TTL = 300; + +const converter = ortbConverter({ + context: { + netRevenue: true, + ttl: DEFAULT_TTL, + }, + processors: pbsExtensions, +}); + +const isBidRequestValid: BidderSpec['isBidRequestValid'] = (request) => { + if (!request.params || typeof request.params.placementId !== 'string') { + return false; + } + + return !!request.params.placementId; +}; + +const buildRequests: BidderSpec['buildRequests'] = (validBidRequests, bidderRequest) => { + const ortbRequest = converter.toORTB({ + bidRequests: validBidRequests, + bidderRequest, + }); + + return { + url: PREBID_URL, + method: 'POST', + data: ortbRequest, + }; +} + +const interpretResponse: BidderSpec['interpretResponse'] = (serverResponse, bidderRequest) => { + const response = converter.fromORTB({ + response: serverResponse.body, + request: bidderRequest.data, + }); + + return response; +}; + +export const spec: BidderSpec = { + buildRequests, + code: BIDDER_CODE, + gvlid: AUDIENZZ_VENDOR_ID, + interpretResponse, + isBidRequestValid, + supportedMediaTypes: [BANNER], +}; + +registerBidder(spec); diff --git a/modules/yandexBidAdapter.md b/modules/yandexBidAdapter.md index ac454285806..9a7684d2644 100644 --- a/modules/yandexBidAdapter.md +++ b/modules/yandexBidAdapter.md @@ -8,40 +8,42 @@ Maintainer: prebid@yandex-team.com # Description -The Yandex Prebid Adapter is designed for seamless integration with Yandex's advertising services. It facilitates effective bidding by leveraging Yandex's robust ad-serving technology, ensuring publishers can maximize their ad revenue through efficient and targeted ad placements. +The Yandex Prebid Adapter is designed for seamless integration with Yandex's advertising services. It facilitates effective bidding by leveraging Yandex's robust ad-serving technology, ensuring publishers can maximize their ad revenue through efficient and targeted ad placements. Please reach out to for the integration guide and more details. For comprehensive auction analytics, consider using the [Yandex Analytics Adapter](https://docs.prebid.org/dev-docs/analytics/yandex.html). This tool provides essential insights into auction dynamics and user interactions, empowering publishers to fine-tune their strategies for optimal ad performance. # Parameters -| Name | Required? | Description | Example | Type | -|---------------|--------------------------------------------|-------------|---------|-----------| -| `placementId` | Yes | Block ID | `123-1` | `String` | -| `pageId` | No
Deprecated. Please use `placementId` | Page ID | `123` | `Integer` | -| `impId` | No
Deprecated. Please use `placementId` | Imp ID | `1` | `Integer` | +| Name | Scope | Description | Example | Type | +|---------------|----------------------------------------|--------------|------------------|-----------| +| `placementId` | Required | Placement ID | `'R-X-123456-1'` | `String` | +| `cur` | Optional. Default value is `'EUR'` | Bid Currency | `'USD'` | `String` | +| `pageId` | `Deprecated`. Please use `placementId` | Page ID | `123` | `Integer` | +| `impId` | `Deprecated`. Please use `placementId` | Imp ID | `1` | `Integer` | # Test Parameters ```javascript var adUnits = [ - { // banner + { // banner example. please check if the 'placementId' is active in Yandex UI code: 'banner-1', mediaTypes: { banner: { - sizes: [[240, 400], [300, 600]], + sizes: [[300, 250], [300, 600]], } }, bids: [ { bidder: 'yandex', params: { - placementId: '346580-1' + placementId: 'R-A-346580-1', + cur: 'USD' }, } ], }, - { // video - code: 'banner-2', + { // video example. please check if the 'placementId' is active in Yandex UI + code: 'video-1', mediaTypes: { video: { sizes: [[640, 480]], @@ -57,13 +59,14 @@ var adUnits = [ { bidder: 'yandex', params: { - placementId: '346580-1' + placementId: 'R-V-346580-1', + cur: 'USD' }, } ], }, - { // native - code: 'banner-3',, + { // native example. please check if the 'placementId' is active in Yandex UI + code: 'native-1', mediaTypes: { native: { title: { @@ -84,7 +87,7 @@ var adUnits = [ len: 90 }, sponsoredBy: { - len: 25, + len: 25 } }, }, @@ -92,7 +95,8 @@ var adUnits = [ { bidder: 'yandex', params: { - placementId: '346580-1' + placementId: 'R-A-346580-2', + cur: 'USD' }, } ], diff --git a/modules/yieldlabBidAdapter.js b/modules/yieldlabBidAdapter.js index e4edb320f86..227e7ea8a12 100644 --- a/modules/yieldlabBidAdapter.js +++ b/modules/yieldlabBidAdapter.js @@ -52,7 +52,8 @@ export const spec = { const timestamp = Date.now(); const query = { ts: timestamp, - json: true}; + json: true + }; _each(validBidRequests, function (bid) { adslotIds.push(bid.params.adslotId); diff --git a/modules/yieldliftBidAdapter.js b/modules/yieldliftBidAdapter.js index ba53f2a6340..a3fdc5bdb5a 100644 --- a/modules/yieldliftBidAdapter.js +++ b/modules/yieldliftBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, deepSetValue, logInfo} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { deepAccess, deepSetValue, logInfo } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://x.yieldlift.com/pbjs'; diff --git a/modules/yieldloveBidAdapter.js b/modules/yieldloveBidAdapter.js index fadcf51cc85..d7743b6580c 100644 --- a/modules/yieldloveBidAdapter.js +++ b/modules/yieldloveBidAdapter.js @@ -1,6 +1,6 @@ -import {registerBidder} from '../src/adapters/bidderFactory.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; import * as utils from '../src/utils.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { BANNER } from '../src/mediaTypes.js'; const ENDPOINT_URL = 'https://s2s.yieldlove-ad-serving.net/openrtb2/auction'; diff --git a/modules/yieldmoBidAdapter.js b/modules/yieldmoBidAdapter.js index 18926496258..eb3ee1de1da 100644 --- a/modules/yieldmoBidAdapter.js +++ b/modules/yieldmoBidAdapter.js @@ -1,4 +1,4 @@ -import {getDNT} from '../libraries/dnt/index.js'; +import { getDNT } from '../libraries/dnt/index.js'; import { deepAccess, deepSetValue, diff --git a/modules/yieldoneAnalyticsAdapter.js b/modules/yieldoneAnalyticsAdapter.js index 23fa0e0eec9..460e8ead751 100644 --- a/modules/yieldoneAnalyticsAdapter.js +++ b/modules/yieldoneAnalyticsAdapter.js @@ -1,5 +1,5 @@ import { isArray, deepClone } from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { ajax } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import { EVENTS } from '../src/constants.js'; import adapterManager from '../src/adapterManager.js'; @@ -66,9 +66,9 @@ function addAdUnitName(params, map) { }); } -const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { +const yieldoneAnalytics = Object.assign(adapter({ analyticsType }), { getUrl() { return url; }, - track({eventType, args = {}}) { + track({ eventType, args = {} }) { if (eventType === EVENTS.BID_REQUESTED) { const reqBidderId = `${args.bidderCode}_${args.auctionId}`; requestedBidders[reqBidderId] = deepClone(args); @@ -83,11 +83,11 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { args.forEach((bid) => { const reqBidId = `${bid.bidId}_${bid.auctionId}`; const reqBidderId = `${bid.bidder}_${bid.auctionId}`; - if (!eventsStorage[bid.auctionId]) eventsStorage[bid.auctionId] = {events: []}; + if (!eventsStorage[bid.auctionId]) eventsStorage[bid.auctionId] = { events: [] }; if ((requestedBidders[reqBidderId] || reqBidders[bid.bidder]) && requestedBids[reqBidId]) { if (!reqBidders[bid.bidder]) { reqBidders[bid.bidder] = requestedBidders[reqBidderId]; - eventsStorage[bid.auctionId].events.push({eventType, params: reqBidders[bid.bidder]}); + eventsStorage[bid.auctionId].events.push({ eventType, params: reqBidders[bid.bidder] }); delete requestedBidders[reqBidderId]; } reqBidders[bid.bidder].bids.push(requestedBids[reqBidId]); @@ -98,7 +98,7 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { currentAuctionId = args.auctionId || currentAuctionId; if (currentAuctionId) { const eventsStorage = yieldoneAnalytics.eventsStorage; - if (!eventsStorage[currentAuctionId]) eventsStorage[currentAuctionId] = {events: []}; + if (!eventsStorage[currentAuctionId]) eventsStorage[currentAuctionId] = { events: [] }; // TODO: is 'page' the right value here? const referrer = args.refererInfo && args.refererInfo.page; if (referrer && referrers[currentAuctionId] !== referrer) { @@ -114,7 +114,7 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { }); } if (!ignoredEvents[eventType]) { - eventsStorage[currentAuctionId].events.push({eventType, params}); + eventsStorage[currentAuctionId].events.push({ eventType, params }); } if ( @@ -125,7 +125,7 @@ const yieldoneAnalytics = Object.assign(adapter({analyticsType}), { auctionManager.getBidsReceived() ); if (yieldoneAnalytics.eventsStorage[currentAuctionId] && yieldoneAnalytics.eventsStorage[currentAuctionId].events.length) { - yieldoneAnalytics.eventsStorage[currentAuctionId].page = {url: referrers[currentAuctionId]}; + yieldoneAnalytics.eventsStorage[currentAuctionId].page = { url: referrers[currentAuctionId] }; yieldoneAnalytics.eventsStorage[currentAuctionId].pubId = pubId; yieldoneAnalytics.eventsStorage[currentAuctionId].wrapper_version = '$prebid.version$'; const adUnitNameMap = makeAdUnitNameMap(); diff --git a/modules/yieldoneBidAdapter.js b/modules/yieldoneBidAdapter.js index 244da9aa3a1..8c91ef18057 100644 --- a/modules/yieldoneBidAdapter.js +++ b/modules/yieldoneBidAdapter.js @@ -1,10 +1,10 @@ -import {deepAccess, isEmpty, isStr, logWarn, parseSizesInput} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {Renderer} from '../src/Renderer.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {getBrowser, getOS} from '../libraries/userAgentUtils/index.js'; -import {browserTypes, osTypes} from '../libraries/userAgentUtils/userAgentTypes.enums.js'; -import {BOL_LIKE_USER_AGENTS} from '../libraries/userAgentUtils/constants.js'; +import { deepAccess, isEmpty, isStr, logWarn, parseSizesInput } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { Renderer } from '../src/Renderer.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { getBrowser, getOS } from '../libraries/userAgentUtils/index.js'; +import { browserTypes, osTypes } from '../libraries/userAgentUtils/userAgentTypes.enums.js'; +import { BOL_LIKE_USER_AGENTS } from '../libraries/userAgentUtils/constants.js'; /** * @typedef {import('../src/adapters/bidderFactory').Bid} Bid @@ -24,7 +24,7 @@ const VIDEO_PLAYER_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/d const CMER_PLAYER_URL = 'https://an.cmertv.com/hb/renderer/cmertv-video-yone-prebid.min.js'; const VIEWABLE_PERCENTAGE_URL = 'https://img.ak.impact-ad.jp/ic/pone/ivt/firstview/js/prebid-adformat-config.js'; -const DEFAULT_VIDEO_SIZE = {w: 640, h: 360}; +const DEFAULT_VIDEO_SIZE = { w: 640, h: 360 }; /** @type {BidderSpec} */ export const spec = { @@ -327,7 +327,7 @@ function getVideoSize(bidRequest, enabledOldFormat = true, enabled1x1 = true) { } const splited = size.split('x'); - const sizeObj = {w: parseInt(splited[0], 10), h: parseInt(splited[1], 10)}; + const sizeObj = { w: parseInt(splited[0], 10), h: parseInt(splited[1], 10) }; const _isValidPlayerSize = !(isEmpty(sizeObj)) && (isFinite(sizeObj.w) && isFinite(sizeObj.h)); if (!_isValidPlayerSize) { return result; diff --git a/modules/yuktamediaAnalyticsAdapter.js b/modules/yuktamediaAnalyticsAdapter.js index e95517faa62..5ff3f2edab6 100644 --- a/modules/yuktamediaAnalyticsAdapter.js +++ b/modules/yuktamediaAnalyticsAdapter.js @@ -1,15 +1,15 @@ -import {buildUrl, generateUUID, getWindowLocation, logError, logInfo, parseSizesInput, parseUrl} from '../src/utils.js'; -import {ajax, fetch} from '../src/ajax.js'; +import { buildUrl, generateUUID, getWindowLocation, logError, logInfo, parseSizesInput, parseUrl } from '../src/utils.js'; +import { ajax, fetch } from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import adapterManager from '../src/adapterManager.js'; import { EVENTS } from '../src/constants.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {getRefererInfo} from '../src/refererDetection.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { getRefererInfo } from '../src/refererDetection.js'; -import {MODULE_TYPE_ANALYTICS} from '../src/activities/modules.js'; +import { MODULE_TYPE_ANALYTICS } from '../src/activities/modules.js'; const MODULE_CODE = 'yuktamedia'; -const storage = getStorageManager({moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE}); +const storage = getStorageManager({ moduleType: MODULE_TYPE_ANALYTICS, moduleName: MODULE_CODE }); const yuktamediaAnalyticsVersion = 'v3.1.0'; let initOptions; diff --git a/modules/zeotapIdPlusIdSystem.js b/modules/zeotapIdPlusIdSystem.js index ca48fde30b3..cbecfb078fe 100644 --- a/modules/zeotapIdPlusIdSystem.js +++ b/modules/zeotapIdPlusIdSystem.js @@ -5,9 +5,9 @@ * @requires module:modules/userId */ import { isStr, isPlainObject } from '../src/utils.js'; -import {submodule} from '../src/hook.js'; -import {getStorageManager} from '../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../src/activities/modules.js'; +import { submodule } from '../src/hook.js'; +import { getStorageManager } from '../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../src/activities/modules.js'; /** * @typedef {import('../modules/userId/index.js').Submodule} Submodule @@ -27,7 +27,7 @@ function readFromLocalStorage() { } export function getStorage() { - return getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: ZEOTAP_MODULE_NAME}); + return getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: ZEOTAP_MODULE_NAME }); } export const storage = getStorage(); diff --git a/modules/zeta_globalBidAdapter.js b/modules/zeta_globalBidAdapter.js index f9fb6f806f5..f5c2952a22b 100644 --- a/modules/zeta_globalBidAdapter.js +++ b/modules/zeta_globalBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER} from '../src/mediaTypes.js'; +import { deepAccess, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -112,13 +112,13 @@ export const spec = { if (request.gdprConsent) { payload.regs.ext = Object.assign( payload.regs.ext, - {gdpr: request.gdprConsent.gdprApplies === true ? 1 : 0} + { gdpr: request.gdprConsent.gdprApplies === true ? 1 : 0 } ); } if (request.gdprConsent && request.gdprConsent.gdprApplies) { payload.user.ext = Object.assign( payload.user.ext, - {consent: request.gdprConsent.consentString} + { consent: request.gdprConsent.consentString } ); } const postUrl = params.definerId !== PREBID_DEFINER_ID ? ENDPOINT_URL.concat('/', params.definerId) : ENDPOINT_URL; diff --git a/modules/zeta_global_sspAnalyticsAdapter.js b/modules/zeta_global_sspAnalyticsAdapter.js index ed4971d39a7..01d6a4a5a77 100644 --- a/modules/zeta_global_sspAnalyticsAdapter.js +++ b/modules/zeta_global_sspAnalyticsAdapter.js @@ -1,11 +1,12 @@ -import {logError} from '../src/utils.js'; -import {ajax} from '../src/ajax.js'; +import { logError } from '../src/utils.js'; +import { ajax } from '../src/ajax.js'; import adapterManager from '../src/adapterManager.js'; -import {EVENTS} from '../src/constants.js'; +import { EVENTS } from '../src/constants.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {config} from '../src/config.js'; -import {parseDomain} from '../src/refererDetection.js'; +import { config } from '../src/config.js'; +import { parseDomain } from '../src/refererDetection.js'; +import { BANNER, VIDEO } from "../src/mediaTypes.js"; const ZETA_GVL_ID = 833; const ADAPTER_CODE = 'zeta_global_ssp'; @@ -32,7 +33,7 @@ function adRenderSucceededHandler(args) { const page = config.getConfig('pageUrl') || args.doc?.location?.host + args.doc?.location?.pathname; const event = { zetaParams: zetaParams, - domain: parseDomain(page, {noLeadingWww: true}), + domain: parseDomain(page, { noLeadingWww: true }), page: page, bid: { adId: args.bid?.adId, @@ -40,12 +41,14 @@ function adRenderSucceededHandler(args) { auctionId: args.bid?.auctionId, creativeId: args.bid?.creativeId, bidder: args.bid?.bidderCode, + dspId: args.bid?.dspId, mediaType: args.bid?.mediaType, size: args.bid?.size, adomain: args.bid?.adserverTargeting?.hb_adomain, timeToRespond: args.bid?.timeToRespond, cpm: args.bid?.cpm, - adUnitCode: args.bid?.adUnitCode + adUnitCode: args.bid?.adUnitCode, + floorData: args.bid?.floorData }, device: { ua: navigator.userAgent @@ -61,15 +64,35 @@ function auctionEndHandler(args) { bidderCode: br?.bidderCode, domain: br?.refererInfo?.domain, page: br?.refererInfo?.page, - bids: br?.bids?.map(b => ({ - bidId: b?.bidId, - auctionId: b?.auctionId, - bidder: b?.bidder, - mediaType: b?.mediaTypes?.video ? 'VIDEO' : (b?.mediaTypes?.banner ? 'BANNER' : undefined), - size: b?.sizes?.filter(s => s && s.length === 2).filter(s => Number.isInteger(s[0]) && Number.isInteger(s[1])).map(s => s[0] + 'x' + s[1]).find(s => s), - device: b?.ortb2?.device, - adUnitCode: b?.adUnitCode - })) + bids: br?.bids?.map(b => { + const mediaType = b?.mediaTypes?.video ? VIDEO : (b?.mediaTypes?.banner ? BANNER : undefined); + let floor; + if (typeof b?.getFloor === 'function') { + try { + const floorInfo = b.getFloor({ + currency: 'USD', + mediaType: mediaType, + size: '*' + }); + if (floorInfo && !isNaN(parseFloat(floorInfo.floor))) { + floor = parseFloat(floorInfo.floor); + } + } catch (e) { + // ignore floor lookup errors + } + } + + return { + bidId: b?.bidId, + auctionId: b?.auctionId, + bidder: b?.bidder, + mediaType: mediaType, + sizes: b?.sizes, + device: b?.ortb2?.device, + adUnitCode: b?.adUnitCode, + floor: floor + }; + }) })), bidsReceived: args.bidsReceived?.map(br => ({ adId: br?.adId, @@ -81,7 +104,8 @@ function auctionEndHandler(args) { adomain: br?.adserverTargeting?.hb_adomain, timeToRespond: br?.timeToRespond, cpm: br?.cpm, - adUnitCode: br?.adUnitCode + adUnitCode: br?.adUnitCode, + dspId: br?.dspId })) } sendEvent(EVENTS.AUCTION_END, event); @@ -92,23 +116,42 @@ function bidTimeoutHandler(args) { zetaParams: zetaParams, domain: args.find(t => t?.ortb2?.site?.domain)?.ortb2?.site?.domain, page: args.find(t => t?.ortb2?.site?.page)?.ortb2?.site?.page, - timeouts: args.map(t => ({ - bidId: t?.bidId, - auctionId: t?.auctionId, - bidder: t?.bidder, - mediaType: t?.mediaTypes?.video ? 'VIDEO' : (t?.mediaTypes?.banner ? 'BANNER' : undefined), - size: t?.sizes?.filter(s => s && s.length === 2).filter(s => Number.isInteger(s[0]) && Number.isInteger(s[1])).map(s => s[0] + 'x' + s[1]).find(s => s), - timeout: t?.timeout, - device: t?.ortb2?.device, - adUnitCode: t?.adUnitCode - })) + timeouts: args.map(t => { + const mediaType = t?.mediaTypes?.video ? VIDEO : (t?.mediaTypes?.banner ? BANNER : undefined); + let floor; + if (typeof t?.getFloor === 'function') { + try { + const floorInfo = t.getFloor({ + currency: 'USD', + mediaType: mediaType, + size: '*' + }); + if (floorInfo && !isNaN(parseFloat(floorInfo.floor))) { + floor = parseFloat(floorInfo.floor); + } + } catch (e) { + // ignore floor lookup errors + } + } + return { + bidId: t?.bidId, + auctionId: t?.auctionId, + bidder: t?.bidder, + mediaType: mediaType, + sizes: t?.sizes, + timeout: t?.timeout, + device: t?.ortb2?.device, + adUnitCode: t?.adUnitCode, + floor: floor + } + }) } sendEvent(EVENTS.BID_TIMEOUT, event); } /// /////////// ADAPTER DEFINITION /////////////////////////// -const baseAdapter = adapter({analyticsType: 'endpoint'}); +const baseAdapter = adapter({ analyticsType: 'endpoint' }); const zetaAdapter = Object.assign({}, baseAdapter, { enableAnalytics(config = {}) { @@ -126,7 +169,7 @@ const zetaAdapter = Object.assign({}, baseAdapter, { baseAdapter.disableAnalytics.apply(this, arguments); }, - track({eventType, args}) { + track({ eventType, args }) { switch (eventType) { case EVENTS.AD_RENDER_SUCCEEDED: adRenderSucceededHandler(args); diff --git a/modules/zeta_global_sspBidAdapter.js b/modules/zeta_global_sspBidAdapter.js index bd0aac1d502..f69a8b4a18d 100644 --- a/modules/zeta_global_sspBidAdapter.js +++ b/modules/zeta_global_sspBidAdapter.js @@ -1,8 +1,8 @@ -import {deepAccess, deepSetValue, isArray, isBoolean, isNumber, isStr, logWarn} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; -import {config} from '../src/config.js'; -import {parseDomain} from '../src/refererDetection.js'; +import { deepAccess, deepSetValue, isArray, isBoolean, isNumber, isStr, logWarn } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; +import { config } from '../src/config.js'; +import { parseDomain } from '../src/refererDetection.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -108,7 +108,7 @@ export const spec = { const floorInfo = request.getFloor({ currency: 'USD', mediaType: impData.video ? 'video' : 'banner', - size: [ impData.video ? impData.video.w : impData.banner.w, impData.video ? impData.video.h : impData.banner.h ] + size: [impData.video ? impData.video.w : impData.banner.w, impData.video ? impData.video.h : impData.banner.h] }); if (floorInfo && floorInfo.floor) { impData.bidfloor = floorInfo.floor; @@ -128,8 +128,8 @@ export const spec = { id: bidderRequest.bidderRequestId, cur: [DEFAULT_CUR], imp: imps, - site: {...bidderRequest?.ortb2?.site, ...params?.site}, - device: {...bidderRequest?.ortb2?.device, ...params?.device}, + site: { ...bidderRequest?.ortb2?.site, ...params?.site }, + device: { ...bidderRequest?.ortb2?.device, ...params?.device }, user: params.user ? params.user : {}, app: params.app ? params.app : {}, ext: { @@ -140,7 +140,7 @@ export const spec = { const rInfo = bidderRequest.refererInfo; if (rInfo) { payload.site.page = cropPage(rInfo.page || rInfo.topmostLocation); - payload.site.domain = parseDomain(payload.site.page, {noLeadingWww: true}); + payload.site.domain = parseDomain(payload.site.page, { noLeadingWww: true }); } payload.device.ua = navigator.userAgent; diff --git a/modules/zmaticooBidAdapter.js b/modules/zmaticooBidAdapter.js index a8a5bc07461..e84c83fc42c 100644 --- a/modules/zmaticooBidAdapter.js +++ b/modules/zmaticooBidAdapter.js @@ -1,6 +1,6 @@ -import {deepAccess, isArray, isBoolean, isNumber, isStr, logWarn, triggerPixel} from '../src/utils.js'; -import {registerBidder} from '../src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from '../src/mediaTypes.js'; +import { deepAccess, isArray, isBoolean, isNumber, isStr, logWarn, triggerPixel } from '../src/utils.js'; +import { registerBidder } from '../src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from '../src/mediaTypes.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -149,10 +149,10 @@ export const spec = { payload.test = params.test; } if (bidderRequest.gdprConsent) { - payload.regs.ext = Object.assign(payload.regs.ext, {gdpr: Number(bidderRequest.gdprConsent.gdprApplies) === 1 ? 1 : 0}); + payload.regs.ext = Object.assign(payload.regs.ext, { gdpr: Number(bidderRequest.gdprConsent.gdprApplies) === 1 ? 1 : 0 }); } if (bidderRequest.gdprConsent && bidderRequest.gdprConsent.gdprApplies) { - payload.user.ext = Object.assign(payload.user.ext, {consent: bidderRequest.gdprConsent.consentString}); + payload.user.ext = Object.assign(payload.user.ext, { consent: bidderRequest.gdprConsent.consentString }); } const postUrl = ENDPOINT_URL; return { diff --git a/package-lock.json b/package-lock.json index c7605928c52..85fc646f8bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prebid.js", - "version": "10.24.0-pre", + "version": "10.28.0-pre", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "prebid.js", - "version": "10.24.0-pre", + "version": "10.28.0-pre", "license": "Apache-2.0", "dependencies": { "@babel/core": "^7.28.4", @@ -2967,29 +2967,6 @@ } } }, - "node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -3981,24 +3958,34 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -6534,11 +6521,10 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6567,9 +6553,9 @@ } }, "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -7194,8 +7180,9 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true }, "node_modules/atob": { "version": "2.1.2", @@ -7223,14 +7210,13 @@ } }, "node_modules/axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "dev": true, - "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -7443,11 +7429,14 @@ } }, "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/basic-auth": { @@ -7467,9 +7456,10 @@ "license": "MIT" }, "node_modules/basic-ftp": { - "version": "5.0.5", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", "dev": true, - "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -7725,15 +7715,15 @@ } }, "node_modules/browserstack-local": { - "version": "1.5.5", + "version": "1.5.11", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.11.tgz", + "integrity": "sha512-RNq0yrezPq7BXXxl/cvsbORfswUQi744po6ECkTEC2RkqNbdPyzewdy4VR9k4QHSzPHTkZx8PeH08veRtfFI8A==", "dev": true, - "license": "MIT", "dependencies": { "agent-base": "^6.0.2", "https-proxy-agent": "^5.0.1", "is-running": "^2.1.0", - "ps-tree": "=1.2.0", - "temp-fs": "^0.9.9" + "tree-kill": "^1.2.2" } }, "node_modules/browserstack/node_modules/agent-base": { @@ -7879,9 +7869,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001766", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", - "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", + "version": "1.0.30001775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", + "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==", "funding": [ { "type": "opencollective", @@ -8220,8 +8210,9 @@ }, "node_modules/combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -9280,8 +9271,9 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -10509,6 +10501,27 @@ } } }, + "node_modules/eslint-plugin-import-x/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint-plugin-import-x/node_modules/brace-expansion": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "dev": true, + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/eslint-plugin-import-x/node_modules/debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -10528,16 +10541,15 @@ } }, "node_modules/eslint-plugin-import-x/node_modules/minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, - "license": "ISC", "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" }, "engines": { - "node": "20 || >=22" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11097,24 +11109,6 @@ "es5-ext": "~0.10.14" } }, - "node_modules/event-stream": { - "version": "3.3.4", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - } - }, - "node_modules/event-stream/node_modules/map-stream": { - "version": "0.1.0", - "dev": true - }, "node_modules/event-target-shim": { "version": "5.0.1", "dev": true, @@ -11447,10 +11441,22 @@ } ] }, + "node_modules/fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ] + }, "node_modules/fast-xml-parser": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz", - "integrity": "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "dev": true, "funding": [ { @@ -11459,7 +11465,8 @@ } ], "dependencies": { - "strnum": "^2.1.0" + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" }, "bin": { "fxparser": "src/cli/cli.js" @@ -11583,11 +11590,10 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -11731,7 +11737,9 @@ "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.6", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "dev": true, "funding": [ { @@ -11739,7 +11747,6 @@ "url": "https://github.com/sponsors/RubenVerborgh" } ], - "license": "MIT", "engines": { "node": ">=4.0" }, @@ -11814,11 +11821,10 @@ "license": "BSD" }, "node_modules/form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, - "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -11867,11 +11873,6 @@ "node": ">= 0.6" } }, - "node_modules/from": { - "version": "0.1.7", - "dev": true, - "license": "MIT" - }, "node_modules/fs-extra": { "version": "11.3.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", @@ -12269,22 +12270,34 @@ "node": ">= 10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -15480,6 +15493,15 @@ "webpack": "^5.0.0" } }, + "node_modules/karma-webpack/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/karma-webpack/node_modules/glob": { "version": "7.2.3", "dev": true, @@ -15500,9 +15522,10 @@ } }, "node_modules/karma-webpack/node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -15511,11 +15534,12 @@ } }, "node_modules/karma-webpack/node_modules/minimatch": { - "version": "9.0.4", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -15525,13 +15549,15 @@ } }, "node_modules/karma-webpack/node_modules/minimatch/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, - "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/karma/node_modules/ansi-styles": { @@ -16167,9 +16193,10 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -16433,9 +16460,10 @@ } }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -16645,22 +16673,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/multimatch/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/multimatch/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/multimatch/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -17600,17 +17640,6 @@ "node": "*" } }, - "node_modules/pause-stream": { - "version": "0.0.11", - "dev": true, - "license": [ - "MIT", - "Apache2" - ], - "dependencies": { - "through": "~2.3" - } - }, "node_modules/pend": { "version": "1.2.0", "dev": true, @@ -17886,20 +17915,6 @@ "dev": true, "license": "MIT" }, - "node_modules/ps-tree": { - "version": "1.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "event-stream": "=3.3.4" - }, - "bin": { - "ps-tree": "bin/ps-tree.js" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/pump": { "version": "3.0.0", "dev": true, @@ -18017,9 +18032,9 @@ } }, "node_modules/qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", "dependencies": { "side-channel": "^1.1.0" }, @@ -18260,9 +18275,10 @@ } }, "node_modules/readdir-glob/node_modules/minimatch": { - "version": "5.1.6", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -18764,9 +18780,9 @@ } }, "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -19411,17 +19427,6 @@ "dev": true, "license": "CC0-1.0" }, - "node_modules/split": { - "version": "0.3.3", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, "node_modules/split2": { "version": "4.2.0", "dev": true, @@ -19496,14 +19501,6 @@ "node": ">= 0.10.0" } }, - "node_modules/stream-combiner": { - "version": "0.0.4", - "dev": true, - "license": "MIT", - "dependencies": { - "duplexer": "~0.1.1" - } - }, "node_modules/stream-composer": { "version": "1.0.2", "dev": true, @@ -19851,17 +19848,16 @@ } }, "node_modules/strnum": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", "dev": true, "funding": [ { "type": "github", "url": "https://github.com/sponsors/NaturalIntelligence" } - ], - "license": "MIT" + ] }, "node_modules/supports-color": { "version": "5.5.0", @@ -19954,47 +19950,6 @@ "streamx": "^2.12.5" } }, - "node_modules/temp-fs": { - "version": "0.9.9", - "dev": true, - "license": "MIT", - "dependencies": { - "rimraf": "~2.5.2" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/temp-fs/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/temp-fs/node_modules/rimraf": { - "version": "2.5.4", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.0.5" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/ternary-stream": { "version": "3.0.0", "dev": true, @@ -20304,6 +20259,15 @@ "node": ">=6" } }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/triple-beam": { "version": "1.4.1", "dev": true, @@ -24084,21 +24048,6 @@ "dev": true, "requires": {} }, - "@isaacs/balanced-match": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", - "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true - }, - "@isaacs/brace-expansion": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", - "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, - "requires": { - "@isaacs/balanced-match": "^4.0.1" - } - }, "@isaacs/cliui": { "version": "8.0.2", "dev": true, @@ -24771,22 +24720,28 @@ "ts-api-utils": "^2.1.0" }, "dependencies": { + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, "brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "requires": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" } }, "semver": { @@ -26481,9 +26436,9 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -26501,9 +26456,9 @@ }, "dependencies": { "ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -26895,6 +26850,8 @@ }, "asynckit": { "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, "atob": { @@ -26909,13 +26866,13 @@ } }, "axios": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", - "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", + "version": "1.13.5", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.5.tgz", + "integrity": "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q==", "dev": true, "requires": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.4", + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, @@ -27043,9 +27000,9 @@ "dev": true }, "baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==" + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==" }, "basic-auth": { "version": "2.0.1", @@ -27061,7 +27018,9 @@ } }, "basic-ftp": { - "version": "5.0.5", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.2.0.tgz", + "integrity": "sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==", "dev": true }, "batch": { @@ -27255,14 +27214,15 @@ } }, "browserstack-local": { - "version": "1.5.5", + "version": "1.5.11", + "resolved": "https://registry.npmjs.org/browserstack-local/-/browserstack-local-1.5.11.tgz", + "integrity": "sha512-RNq0yrezPq7BXXxl/cvsbORfswUQi744po6ECkTEC2RkqNbdPyzewdy4VR9k4QHSzPHTkZx8PeH08veRtfFI8A==", "dev": true, "requires": { "agent-base": "^6.0.2", "https-proxy-agent": "^5.0.1", "is-running": "^2.1.0", - "ps-tree": "=1.2.0", - "temp-fs": "^0.9.9" + "tree-kill": "^1.2.2" } }, "buffer-crc32": { @@ -27338,9 +27298,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001766", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", - "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==" + "version": "1.0.30001775", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001775.tgz", + "integrity": "sha512-s3Qv7Lht9zbVKE9XoTyRG6wVDCKdtOFIjBGg3+Yhn6JaytuNKPIjBMTMIY1AnOH3seL5mvF+x33oGAyK3hVt3A==" }, "chai": { "version": "4.4.1", @@ -27558,6 +27518,8 @@ }, "combined-stream": { "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -28237,6 +28199,8 @@ }, "delayed-stream": { "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "depd": { @@ -29175,6 +29139,21 @@ "unrs-resolver": "^1.9.2" }, "dependencies": { + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, + "brace-expansion": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", + "dev": true, + "requires": { + "balanced-match": "^4.0.2" + } + }, "debug": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", @@ -29185,12 +29164,12 @@ } }, "minimatch": { - "version": "10.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", - "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "version": "10.2.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", + "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, "requires": { - "@isaacs/brace-expansion": "^5.0.0" + "brace-expansion": "^5.0.2" } }, "ms": { @@ -29414,25 +29393,6 @@ "es5-ext": "~0.10.14" } }, - "event-stream": { - "version": "3.3.4", - "dev": true, - "requires": { - "duplexer": "~0.1.1", - "from": "~0", - "map-stream": "~0.1.0", - "pause-stream": "0.0.11", - "split": "0.3", - "stream-combiner": "~0.0.4", - "through": "~2.3.1" - }, - "dependencies": { - "map-stream": { - "version": "0.1.0", - "dev": true - } - } - }, "event-target-shim": { "version": "5.0.1", "dev": true @@ -29664,13 +29624,20 @@ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==" }, + "fast-xml-builder": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", + "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", + "dev": true + }, "fast-xml-parser": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.3.4.tgz", - "integrity": "sha512-EFd6afGmXlCx8H8WTZHhAoDaWaGyuIBoZJ2mknrNxug+aZKjkp0a0dlars9Izl+jF+7Gu1/5f/2h68cQpe0IiA==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", + "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", "dev": true, "requires": { - "strnum": "^2.1.0" + "fast-xml-builder": "^1.0.0", + "strnum": "^2.1.2" } }, "fastest-levenshtein": { @@ -29751,9 +29718,9 @@ } }, "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -29853,7 +29820,9 @@ "dev": true }, "follow-redirects": { - "version": "1.15.6", + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "dev": true }, "for-each": { @@ -29893,9 +29862,9 @@ "dev": true }, "form-data": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", - "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -29926,10 +29895,6 @@ "fresh": { "version": "0.5.2" }, - "from": { - "version": "0.1.7", - "dev": true - }, "fs-extra": { "version": "11.3.1", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", @@ -30144,20 +30109,28 @@ "path-scurry": "^1.11.1" }, "dependencies": { + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, "brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "requires": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" } }, "minimatch": { - "version": "9.0.5", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" } } } @@ -32351,6 +32324,12 @@ "webpack-merge": "^4.1.5" }, "dependencies": { + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, "glob": { "version": "7.2.3", "dev": true, @@ -32364,7 +32343,9 @@ }, "dependencies": { "minimatch": { - "version": "3.1.2", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -32373,19 +32354,21 @@ } }, "minimatch": { - "version": "9.0.4", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "dependencies": { "brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "requires": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" } } } @@ -32735,7 +32718,9 @@ } }, "minimatch": { - "version": "3.1.2", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.4.tgz", + "integrity": "sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -32903,7 +32888,9 @@ } }, "minimatch": { - "version": "5.1.6", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -33038,22 +33025,28 @@ "minimatch": "^9.0.3" }, "dependencies": { + "balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true + }, "brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", + "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "requires": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" } }, "minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.7.tgz", + "integrity": "sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" } } } @@ -33629,13 +33622,6 @@ "version": "1.1.1", "dev": true }, - "pause-stream": { - "version": "0.0.11", - "dev": true, - "requires": { - "through": "~2.3" - } - }, "pend": { "version": "1.2.0", "dev": true @@ -33810,13 +33796,6 @@ "version": "1.0.1", "dev": true }, - "ps-tree": { - "version": "1.2.0", - "dev": true, - "requires": { - "event-stream": "=3.3.4" - } - }, "pump": { "version": "3.0.0", "dev": true, @@ -33890,9 +33869,9 @@ "dev": true }, "qs": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", - "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", + "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", "requires": { "side-channel": "^1.1.0" } @@ -34046,7 +34025,9 @@ } }, "minimatch": { - "version": "5.1.6", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.8.tgz", + "integrity": "sha512-7RN35vit8DeBclkofOVmBY0eDAZZQd1HzmukRdSyz95CRh8FT54eqnbj0krQr3mrHR6sfRyYkyhwBWjoV5uqlQ==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -34357,9 +34338,9 @@ }, "dependencies": { "ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -34803,13 +34784,6 @@ "version": "3.0.18", "dev": true }, - "split": { - "version": "0.3.3", - "dev": true, - "requires": { - "through": "2" - } - }, "split2": { "version": "4.2.0", "dev": true @@ -34856,13 +34830,6 @@ "version": "3.0.2", "dev": true }, - "stream-combiner": { - "version": "0.0.4", - "dev": true, - "requires": { - "duplexer": "~0.1.1" - } - }, "stream-composer": { "version": "1.0.2", "dev": true, @@ -35103,9 +35070,9 @@ "dev": true }, "strnum": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", + "integrity": "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ==", "dev": true }, "supports-color": { @@ -35167,34 +35134,6 @@ "streamx": "^2.12.5" } }, - "temp-fs": { - "version": "0.9.9", - "dev": true, - "requires": { - "rimraf": "~2.5.2" - }, - "dependencies": { - "glob": { - "version": "7.2.3", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "rimraf": { - "version": "2.5.4", - "dev": true, - "requires": { - "glob": "^7.0.5" - } - } - } - }, "ternary-stream": { "version": "3.0.0", "dev": true, @@ -35398,6 +35337,12 @@ "version": "3.0.1", "dev": true }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, "triple-beam": { "version": "1.4.1", "dev": true diff --git a/package.json b/package.json index c7ca0275009..c82ac4ff4f5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "prebid.js", - "version": "10.24.0-pre", + "version": "10.28.0-pre", "description": "Header Bidding Management Library", "main": "dist/src/prebid.public.ts", "exports": { diff --git a/plugins/eslint/approvedLoadExternalScriptPaths.js b/plugins/eslint/approvedLoadExternalScriptPaths.js new file mode 100644 index 00000000000..0eab8545924 --- /dev/null +++ b/plugins/eslint/approvedLoadExternalScriptPaths.js @@ -0,0 +1,48 @@ +// List of exact file paths or folder paths where loadExternalScript is allowed to be used. +// Folder paths (without file extension) allow all files in that folder. +const APPROVED_LOAD_EXTERNAL_SCRIPT_PATHS = [ + // Prebid maintained modules: + 'src/debugging.js', + 'src/Renderer.js', + // RTD modules: + 'modules/aaxBlockmeterRtdProvider.js', + 'modules/adagioRtdProvider.js', + 'modules/adlooxAnalyticsAdapter.js', + 'modules/arcspanRtdProvider.js', + 'modules/airgridRtdProvider.js', + 'modules/browsiRtdProvider.js', + 'modules/brandmetricsRtdProvider.js', + 'modules/cleanioRtdProvider.js', + 'modules/humansecurityMalvDefenseRtdProvider.js', + 'modules/humansecurityRtdProvider.ts', + 'modules/confiantRtdProvider.js', + 'modules/contxtfulRtdProvider.js', + 'modules/hadronRtdProvider.js', + 'modules/mediafilterRtdProvider.js', + 'modules/medianetRtdProvider.js', + 'modules/azerionedgeRtdProvider.js', + 'modules/a1MediaRtdProvider.js', + 'modules/geoedgeRtdProvider.js', + 'modules/qortexRtdProvider.js', + 'modules/dynamicAdBoostRtdProvider.js', + 'modules/51DegreesRtdProvider.js', + 'modules/symitriDapRtdProvider.js', + 'modules/wurflRtdProvider.js', + 'modules/nodalsAiRtdProvider.js', + 'modules/anonymisedRtdProvider.js', + 'modules/optableRtdProvider.js', + 'modules/oftmediaRtdProvider.js', + 'modules/panxoRtdProvider.js', + // UserId Submodules + 'modules/justIdSystem.js', + 'modules/tncIdSystem.js', + 'modules/ftrackIdSystem.js', + 'modules/id5IdSystem.js', + // Test files + '**/*spec.js', + '**/*spec.ts', + '**/test/**/*', +]; + +module.exports = APPROVED_LOAD_EXTERNAL_SCRIPT_PATHS; + diff --git a/src/Renderer.js b/src/Renderer.js index c9d68b48993..fee6c865e88 100644 --- a/src/Renderer.js +++ b/src/Renderer.js @@ -2,7 +2,7 @@ import { loadExternalScript } from './adloader.js'; import { logError, logWarn, logMessage } from './utils.js'; -import {getGlobal} from './prebidGlobal.js'; +import { getGlobal } from './prebidGlobal.js'; import { MODULE_TYPE_PREBID } from './activities/modules.js'; const pbjsInstance = getGlobal(); diff --git a/src/activities/activities.js b/src/activities/activities.js index 53d73e26c3b..f436222603b 100644 --- a/src/activities/activities.js +++ b/src/activities/activities.js @@ -60,3 +60,8 @@ export const LOAD_EXTERNAL_SCRIPT = 'loadExternalScript'; * accessRequestCredentials: setting withCredentials flag in ajax request config */ export const ACTIVITY_ACCESS_REQUEST_CREDENTIALS = 'accessRequestCredentials'; + +/** + * acceptBid: a bid is about to be accepted. + */ +export const ACTIVITY_ADD_BID_RESPONSE = 'acceptBid'; diff --git a/src/activities/activityParams.js b/src/activities/activityParams.js index f33ceb2a9a4..9eb1ea2d69d 100644 --- a/src/activities/activityParams.js +++ b/src/activities/activityParams.js @@ -1,5 +1,5 @@ import adapterManager from '../adapterManager.js'; -import {activityParamsBuilder} from './params.js'; +import { activityParamsBuilder } from './params.js'; /** * Utility function for building common activity parameters - broken out to its own diff --git a/src/activities/params.js b/src/activities/params.js index 975d9b66cc4..d036a1de023 100644 --- a/src/activities/params.js +++ b/src/activities/params.js @@ -1,5 +1,5 @@ -import {MODULE_TYPE_BIDDER} from './modules.js'; -import {hook} from '../hook.js'; +import { MODULE_TYPE_BIDDER } from './modules.js'; +import { hook } from '../hook.js'; /** * Component ID - who is trying to perform the activity? diff --git a/src/activities/redactor.ts b/src/activities/redactor.ts index d58dd3588ce..658b1792dc0 100644 --- a/src/activities/redactor.ts +++ b/src/activities/redactor.ts @@ -1,6 +1,6 @@ -import {deepAccess} from '../utils.js'; -import {config} from '../config.js'; -import {isActivityAllowed, registerActivityControl} from './rules.js'; +import { deepAccess } from '../utils.js'; +import { config } from '../config.js'; +import { isActivityAllowed, registerActivityControl } from './rules.js'; import { ACTIVITY_TRANSMIT_EIDS, ACTIVITY_TRANSMIT_PRECISE_GEO, @@ -224,6 +224,6 @@ declare module '../config' { // by default, TIDs are off since version 8 registerActivityControl(ACTIVITY_TRANSMIT_TID, 'enableTIDs config', () => { if (!config.getConfig('enableTIDs')) { - return {allow: false, reason: 'TIDs are disabled'} + return { allow: false, reason: 'TIDs are disabled' } } }); diff --git a/src/activities/rules.js b/src/activities/rules.js index db4eeab7241..7902dadad5d 100644 --- a/src/activities/rules.js +++ b/src/activities/rules.js @@ -1,5 +1,5 @@ -import {prefixLog} from '../utils.js'; -import {ACTIVITY_PARAM_COMPONENT} from './params.js'; +import { prefixLog } from '../utils.js'; +import { ACTIVITY_PARAM_COMPONENT } from './params.js'; /** * @param logger @@ -19,16 +19,16 @@ export function ruleRegistry(logger = prefixLog('Activity control:')) { res = rule(params); } catch (e) { logger.logError(`Exception in rule ${name} for '${activity}'`, e); - res = {allow: false, reason: e}; + res = { allow: false, reason: e }; } - return res && Object.assign({activity, name, component: params[ACTIVITY_PARAM_COMPONENT]}, res); + return res && Object.assign({ activity, name, component: params[ACTIVITY_PARAM_COMPONENT] }, res); } const dupes = {}; const DEDUPE_INTERVAL = 1000; // eslint-disable-next-line no-restricted-syntax - function logResult({activity, name, allow, reason, component}) { + function logResult({ activity, name, allow, reason, component }) { const msg = `${name} ${allow ? 'allowed' : 'denied'} '${activity}' for '${component}'${reason ? ':' : ''}`; const deduping = dupes.hasOwnProperty(msg); if (deduping) { diff --git a/src/adRendering.ts b/src/adRendering.ts index 25aba25a59f..dc214734dd9 100644 --- a/src/adRendering.ts +++ b/src/adRendering.ts @@ -9,21 +9,21 @@ import { triggerPixel } from './utils.js'; import * as events from './events.js'; -import {AD_RENDER_FAILED_REASON, BID_STATUS, EVENTS, MESSAGES, PB_LOCATOR} from './constants.js'; -import {config} from './config.js'; -import {executeRenderer, isRendererRequired} from './Renderer.js'; -import {VIDEO} from './mediaTypes.js'; -import {auctionManager} from './auctionManager.js'; -import {getCreativeRenderer} from './creativeRenderers.js'; -import {hook} from './hook.js'; -import {fireNativeTrackers} from './native.js'; +import { AD_RENDER_FAILED_REASON, BID_STATUS, EVENTS, MESSAGES, PB_LOCATOR } from './constants.js'; +import { config } from './config.js'; +import { executeRenderer, isRendererRequired } from './Renderer.js'; +import { VIDEO } from './mediaTypes.js'; +import { auctionManager } from './auctionManager.js'; +import { getCreativeRenderer } from './creativeRenderers.js'; +import { hook } from './hook.js'; +import { fireNativeTrackers } from './native.js'; import adapterManager from './adapterManager.js'; -import {useMetrics} from './utils/perfMetrics.js'; -import {filters} from './targeting.js'; -import {EVENT_TYPE_WIN, parseEventTrackers, TRACKER_METHOD_IMG} from './eventTrackers.js'; -import type {Bid} from "./bidfactory.ts"; -import {yieldsIf} from "./utils/yield.ts"; -import {PbPromise} from "./utils/promise.ts"; +import { useMetrics } from './utils/perfMetrics.js'; +import { filters } from './targeting.js'; +import { EVENT_TYPE_WIN, parseEventTrackers, TRACKER_METHOD_IMG } from './eventTrackers.js'; +import type { Bid } from "./bidfactory.ts"; +import { yieldsIf } from "./utils/yield.ts"; +import { PbPromise } from "./utils/promise.ts"; const { AD_RENDER_FAILED, AD_RENDER_SUCCEEDED, STALE_RENDER, BID_WON, EXPIRED_RENDER } = EVENTS; const { EXCEPTION } = AD_RENDER_FAILED_REASON; @@ -126,7 +126,7 @@ type AdRenderSucceededData = { * (Note: Invocation of this function indicates that the render function did not generate an error, it does not guarantee that tracking for this event has occurred yet.) */ export function emitAdRenderSucceeded({ doc, bid, id }) { - const data: AdRenderSucceededData = { doc, bid, adId: id}; + const data: AdRenderSucceededData = { doc, bid, adId: id }; adapterManager.callAdRenderSucceededBidder(bid.adapterCode || bid.bidder, bid); @@ -180,7 +180,7 @@ export function handleCreativeEvent(data, bidResponse) { } } -export function handleNativeMessage(data, bidResponse, {resizeFn, fireTrackers = fireNativeTrackers}) { +export function handleNativeMessage(data, bidResponse, { resizeFn, fireTrackers = fireNativeTrackers }) { switch (data.action) { case 'resizeNativeHeight': resizeFn(data.width, data.height); @@ -211,7 +211,7 @@ type RenderOptions = { } export const getRenderingData = hook('sync', function (bidResponse: Bid, options?: RenderOptions): Record { - const {ad, adUrl, cpm, originalCpm, width, height, instl} = bidResponse + const { ad, adUrl, cpm, originalCpm, width, height, instl } = bidResponse const repl = { AUCTION_PRICE: originalCpm || cpm, CLICKTHROUGH: options?.clickUrl || '' @@ -225,7 +225,7 @@ export const getRenderingData = hook('sync', function (bidResponse: Bid, options }; }) -export const doRender = hook('sync', function({renderFn, resizeFn, bidResponse, options, doc, isMainDocument = doc === document && !inIframe()}) { +export const doRender = hook('sync', function({ renderFn, resizeFn, bidResponse, options, doc, isMainDocument = doc === document && !inIframe() }) { const videoBid = (FEATURES.VIDEO && bidResponse.mediaType === VIDEO) if (isMainDocument || videoBid) { emitAdRenderFail({ @@ -237,8 +237,8 @@ export const doRender = hook('sync', function({renderFn, resizeFn, bidResponse, return; } const data = getRenderingData(bidResponse, options); - renderFn(Object.assign({adId: bidResponse.adId}, data)); - const {width, height} = data; + renderFn(Object.assign({ adId: bidResponse.adId }, data)); + const { width, height } = data; if ((width ?? height) != null) { resizeFn(width, height); } @@ -246,17 +246,17 @@ export const doRender = hook('sync', function({renderFn, resizeFn, bidResponse, doRender.before(function (next, args) { // run renderers from a high priority hook to allow the video module to insert itself between this and "normal" rendering. - const {bidResponse, doc} = args; + const { bidResponse, doc } = args; if (isRendererRequired(bidResponse.renderer)) { executeRenderer(bidResponse.renderer, bidResponse, doc); - emitAdRenderSucceeded({doc, bid: bidResponse, id: bidResponse.adId}) + emitAdRenderSucceeded({ doc, bid: bidResponse, id: bidResponse.adId }) next.bail(); } else { next(args); } }, 100) -export function handleRender({renderFn, resizeFn, adId, options, bidResponse, doc}) { +export function handleRender({ renderFn, resizeFn, adId, options, bidResponse, doc }) { deferRendering(bidResponse, () => { if (bidResponse == null) { emitAdRenderFail({ @@ -282,7 +282,7 @@ export function handleRender({renderFn, resizeFn, adId, options, bidResponse, do } try { - doRender({renderFn, resizeFn, bidResponse, options, doc}); + doRender({ renderFn, resizeFn, bidResponse, options, doc }); } catch (e) { emitAdRenderFail({ reason: AD_RENDER_FAILED_REASON.EXCEPTION, @@ -343,7 +343,7 @@ config.getConfig('auctionOptions', (opts) => { export const renderAdDirect = yieldsIf(() => !legacyRender, function renderAdDirect(doc, adId, options) { let bid; function fail(reason, message) { - emitAdRenderFail(Object.assign({id: adId, bid}, {reason, message})); + emitAdRenderFail(Object.assign({ id: adId, bid }, { reason, message })); } function resizeFn(width, height) { const frame = doc.defaultView?.frameElement; @@ -358,7 +358,7 @@ export const renderAdDirect = yieldsIf(() => !legacyRender, function renderAdDir } } } - const messageHandler = creativeMessageHandler({resizeFn}); + const messageHandler = creativeMessageHandler({ resizeFn }); function waitForDocumentReady(doc) { return new PbPromise((resolve) => { @@ -374,7 +374,7 @@ export const renderAdDirect = yieldsIf(() => !legacyRender, function renderAdDir if (adData.ad && legacyRender) { doc.write(adData.ad); doc.close(); - emitAdRenderSucceeded({doc, bid, id: bid.adId}); + emitAdRenderSucceeded({ doc, bid, id: bid.adId }); } else { PbPromise.all([ getCreativeRenderer(bid), @@ -384,7 +384,7 @@ export const renderAdDirect = yieldsIf(() => !legacyRender, function renderAdDir mkFrame: createIframe, }, doc.defaultView)) .then( - () => emitAdRenderSucceeded({doc, bid, id: bid.adId}), + () => emitAdRenderSucceeded({ doc, bid, id: bid.adId }), (e) => { fail(e?.reason || AD_RENDER_FAILED_REASON.EXCEPTION, e?.message) e?.stack && logError(e); @@ -401,7 +401,7 @@ export const renderAdDirect = yieldsIf(() => !legacyRender, function renderAdDir } else { getBidToRender(adId, true, (bidResponse) => { bid = bidResponse; - handleRender({renderFn, resizeFn, adId, options: {clickUrl: options?.clickThrough}, bidResponse, doc}); + handleRender({ renderFn, resizeFn, adId, options: { clickUrl: options?.clickThrough }, bidResponse, doc }); }); } } catch (e) { diff --git a/src/adUnits.ts b/src/adUnits.ts index 2cb94f788e3..a1aced172ef 100644 --- a/src/adUnits.ts +++ b/src/adUnits.ts @@ -1,8 +1,8 @@ -import type {AdUnitCode, BidderCode, ContextIdentifiers, Size} from "./types/common.d.ts"; -import type {ORTBImp} from "./types/ortb/request.d.ts"; -import type {Bid} from "./bidfactory.ts"; -import type {MediaTypes} from "./mediaTypes.ts"; -import type {DeepPartial} from "./types/objects.d.ts"; +import type { AdUnitCode, BidderCode, ContextIdentifiers, Size } from "./types/common.d.ts"; +import type { ORTBImp } from "./types/ortb/request.d.ts"; +import type { Bid } from "./bidfactory.ts"; +import type { MediaTypes } from "./mediaTypes.ts"; +import type { DeepPartial } from "./types/objects.d.ts"; export interface RendererConfig { /** diff --git a/src/adapterManager.ts b/src/adapterManager.ts index 1483899029f..81c63be66bc 100644 --- a/src/adapterManager.ts +++ b/src/adapterManager.ts @@ -22,11 +22,11 @@ import { timestamp, uniques, } from './utils.js'; -import {decorateAdUnitsWithNativeParams, nativeAdapters} from './native.js'; -import {newBidder} from './adapters/bidderFactory.js'; -import {ajaxBuilder} from './ajax.js'; -import {config, RANDOM} from './config.js'; -import {hook} from './hook.js'; +import { decorateAdUnitsWithNativeParams, nativeAdapters } from './native.js'; +import { newBidder } from './adapters/bidderFactory.js'; +import { ajaxBuilder } from './ajax.js'; +import { config, RANDOM } from './config.js'; +import { hook } from './hook.js'; import { type AdUnit, type AdUnitBid, @@ -40,18 +40,18 @@ import { incrementBidderWinsCounter, incrementRequestsCounter } from './adUnits.js'; -import {getRefererInfo, type RefererInfo} from './refererDetection.js'; -import {GDPR_GVLIDS, gdprDataHandler, gppDataHandler, uspDataHandler,} from './consentHandler.js'; +import { getRefererInfo, type RefererInfo } from './refererDetection.js'; +import { GDPR_GVLIDS, gdprDataHandler, gppDataHandler, uspDataHandler, } from './consentHandler.js'; import * as events from './events.js'; -import {EVENTS, S2S} from './constants.js'; -import {type Metrics, useMetrics} from './utils/perfMetrics.js'; -import {auctionManager} from './auctionManager.js'; -import {MODULE_TYPE_ANALYTICS, MODULE_TYPE_BIDDER, MODULE_TYPE_PREBID} from './activities/modules.js'; -import {isActivityAllowed} from './activities/rules.js'; -import {ACTIVITY_FETCH_BIDS, ACTIVITY_REPORT_ANALYTICS} from './activities/activities.js'; -import {ACTIVITY_PARAM_ANL_CONFIG, ACTIVITY_PARAM_S2S_NAME, activityParamsBuilder} from './activities/params.js'; -import {redactor} from './activities/redactor.js'; -import {EVENT_TYPE_IMPRESSION, parseEventTrackers, TRACKER_METHOD_IMG} from './eventTrackers.js'; +import { EVENTS, S2S } from './constants.js'; +import { type Metrics, useMetrics } from './utils/perfMetrics.js'; +import { auctionManager } from './auctionManager.js'; +import { MODULE_TYPE_ANALYTICS, MODULE_TYPE_BIDDER, MODULE_TYPE_PREBID } from './activities/modules.js'; +import { isActivityAllowed } from './activities/rules.js'; +import { ACTIVITY_FETCH_BIDS, ACTIVITY_REPORT_ANALYTICS } from './activities/activities.js'; +import { ACTIVITY_PARAM_ANL_CONFIG, ACTIVITY_PARAM_S2S_NAME, activityParamsBuilder } from './activities/params.js'; +import { redactor } from './activities/redactor.js'; +import { EVENT_TYPE_IMPRESSION, parseEventTrackers, TRACKER_METHOD_IMG } from './eventTrackers.js'; import type { AdUnitCode, BidderCode, @@ -61,15 +61,15 @@ import type { ORTBFragments, Size, StorageDisclosure } from "./types/common.d.ts"; -import type {DeepPartial} from "./types/objects.d.ts"; -import type {ORTBRequest} from "./types/ortb/request.d.ts"; +import type { DeepPartial } from "./types/objects.d.ts"; +import type { ORTBRequest } from "./types/ortb/request.d.ts"; import type { AnalyticsConfig, AnalyticsProvider, AnalyticsProviderConfig, } from "../libraries/analyticsAdapter/AnalyticsAdapter.ts"; -import {getGlobal} from "./prebidGlobal.ts"; +import { getGlobal } from "./prebidGlobal.ts"; -export {gdprDataHandler, gppDataHandler, uspDataHandler, coppaDataHandler} from './consentHandler.js'; +export { gdprDataHandler, gppDataHandler, uspDataHandler, coppaDataHandler } from './consentHandler.js'; export const PBS_ADAPTER_NAME = 'pbsBidAdapter'; export const PARTITIONS = { @@ -84,7 +84,7 @@ export const dep = { const _bidderRegistry = {}; const _aliasRegistry: { [aliasCode: BidderCode]: BidderCode } = {}; -const _analyticsRegistry: { [P in AnalyticsProvider]?: { adapter: AnalyticsAdapter

, gvlid?: number }} = {}; +const _analyticsRegistry: { [P in AnalyticsProvider]?: { adapter: AnalyticsAdapter

, gvlid?: number } } = {}; let _s2sConfigs = []; config.getConfig('s2sConfig', config => { @@ -93,7 +93,7 @@ config.getConfig('s2sConfig', config => { } }); -const activityParams = activityParamsBuilder((alias) => adapterManager.resolveAlias(alias)); +export const activityParams = activityParamsBuilder((alias) => adapterManager.resolveAlias(alias)); function getConfigName(s2sConfig) { // According to our docs, "module" bid (stored impressions) @@ -155,7 +155,7 @@ export interface BaseBidRequest extends ContextIdentifiers, Pick; } -export interface StoredBidRequest extends BaseBidRequest, Omit<{[K in keyof AdUnitBidderBid]?: undefined}, keyof BaseBidRequest> { +export interface StoredBidRequest extends BaseBidRequest, Omit<{ [K in keyof AdUnitBidderBid]?: undefined }, keyof BaseBidRequest> { bidder: null; src: typeof S2S.SRC; } @@ -247,11 +247,11 @@ export type AnalyticsAdapter

= StorageDisclosure & gvlid?: number | ((config: AnalyticsConfig

) => number); } -function getBids({bidderCode, auctionId, bidderRequestId, adUnits, src, metrics, getTid}: GetBidsOptions): BidRequest[] { +function getBids({ bidderCode, auctionId, bidderRequestId, adUnits, src, metrics, getTid }: GetBidsOptions): BidRequest[] { return adUnits.reduce((result, adUnit) => { const bids = adUnit.bids.filter(bid => bid.bidder === bidderCode); if (bidderCode == null && bids.length === 0 && (adUnit as PBSAdUnit).s2sBid != null) { - bids.push({bidder: null}); + bids.push({ bidder: null }); } result.push( bids.reduce((bids: BidRequest[], bid: BidRequest) => { @@ -262,7 +262,7 @@ function getBids({bidde {}, adUnit.ortb2Imp, bid.ortb2Imp, - {ext: {tid, tidSource}}) + { ext: { tid, tidSource } }) }, getDefinedParams(adUnit, ADUNIT_BID_PROPERTIES), ); @@ -313,7 +313,7 @@ function getBids({bidde * @param s2sConfig null if the adUnit is being routed to a client adapter; otherwise the s2s adapter's config * @returns the subset of `bids` that are pertinent for the given `s2sConfig` */ -export const filterBidsForAdUnit = hook('sync', function(bids, s2sConfig, {getS2SBidders = getS2SBidderSet} = {}) { +export const filterBidsForAdUnit = hook('sync', function(bids, s2sConfig, { getS2SBidders = getS2SBidderSet } = {}) { if (s2sConfig == null) { return bids; } else { @@ -367,7 +367,7 @@ function getAdUnitCopyForPrebidServer(adUnits: AdUnit[], s2sConfig) { }); // don't send empty requests - return {adUnits: adUnitsCopy, hasModuleBids}; + return { adUnits: adUnitsCopy, hasModuleBids }; } function getAdUnitCopyForClientAdapters(adUnits: AdUnit[]) { @@ -417,13 +417,13 @@ export function getS2SBidderSet(s2sConfigs) { * @returns {Object} return.client - Array of bidder codes that should be routed to client adapters. * @returns {Object} return.server - Array of bidder codes that should be routed to server adapters. */ -export function _partitionBidders (adUnits, s2sConfigs, {getS2SBidders = getS2SBidderSet} = {}) { +export function _partitionBidders (adUnits, s2sConfigs, { getS2SBidders = getS2SBidderSet } = {}) { const serverBidders = getS2SBidders(s2sConfigs); return getBidderCodes(adUnits).reduce((memo, bidder) => { const partition = serverBidders.has(bidder) ? PARTITIONS.SERVER : PARTITIONS.CLIENT; memo[partition].push(bidder); return memo; - }, {[PARTITIONS.CLIENT]: [], [PARTITIONS.SERVER]: []}) + }, { [PARTITIONS.CLIENT]: [], [PARTITIONS.SERVER]: [] }) } export const partitionBidders = hook('sync', _partitionBidders, 'partitionBidders'); @@ -506,17 +506,68 @@ const adapterManager = { .filter(uniques) .forEach(incrementAuctionsCounter); - let {[PARTITIONS.CLIENT]: clientBidders, [PARTITIONS.SERVER]: serverBidders} = partitionBidders(adUnits, _s2sConfigs); + const ortb2 = ortb2Fragments.global || {}; + const bidderOrtb2 = ortb2Fragments.bidder || {}; + + const getTid = tidFactory(); + + const getCacheKey = (bidderCode: BidderCode, s2sActivityParams?): string => { + const s2sName = s2sActivityParams != null ? s2sActivityParams[ACTIVITY_PARAM_S2S_NAME] : ''; + return s2sName ? `${bidderCode}:${s2sName}` : `${bidderCode}:`; + }; + + const mergeBidderFpd = (() => { + const fpdCache: any = {}; + return function(auctionId: string, bidderCode: BidderCode, s2sActivityParams?) { + const cacheKey = getCacheKey(bidderCode, s2sActivityParams); + const redact = dep.redact( + s2sActivityParams != null + ? s2sActivityParams + : activityParams(MODULE_TYPE_BIDDER, bidderCode) + ); + if (fpdCache[cacheKey] !== undefined) { + return [fpdCache[cacheKey], redact]; + } + const [tid, tidSource] = getTid(bidderCode, auctionId, bidderOrtb2[bidderCode]?.source?.tid ?? ortb2.source?.tid); + const fpd = Object.freeze(redact.ortb2(mergeDeep( + {}, + ortb2, + bidderOrtb2[bidderCode], + { + source: { + tid, + ext: { tidSource } + } + } + ))); + fpdCache[cacheKey] = fpd; + return [fpd, redact]; + } + })(); + + let { [PARTITIONS.CLIENT]: clientBidders, [PARTITIONS.SERVER]: serverBidders } = partitionBidders(adUnits, _s2sConfigs); const allowedBidders = new Set(); adUnits.forEach(au => { if (!isPlainObject(au.mediaTypes)) { au.mediaTypes = {}; } + // filter out bidders that cannot participate in the auction - au.bids = au.bids.filter((bid) => !bid.bidder || dep.isAllowed(ACTIVITY_FETCH_BIDS, activityParams(MODULE_TYPE_BIDDER, bid.bidder, { - isS2S: serverBidders.includes(bid.bidder) && !clientBidders.includes(bid.bidder) - }))) + au.bids = au.bids.filter((bid) => { + if (!bid.bidder) { + return true; + } + const [ortb2] = mergeBidderFpd(auctionId, bid.bidder); + const isS2S = serverBidders.includes(bid.bidder) && !clientBidders.includes(bid.bidder); + return dep.isAllowed(ACTIVITY_FETCH_BIDS, activityParams(MODULE_TYPE_BIDDER, bid.bidder, { + bid, + ortb2, + adUnit: au, + auctionId, + isS2S + })); + }); au.bids.forEach(bid => { allowedBidders.add(bid.bidder); }); @@ -535,29 +586,8 @@ const adapterManager = { const bidRequests: BidderRequest[] = []; - const ortb2 = ortb2Fragments.global || {}; - const bidderOrtb2 = ortb2Fragments.bidder || {}; - - const getTid = tidFactory(); - function addOrtb2>(bidderRequest: Partial, s2sActivityParams?): T { - const redact = dep.redact( - s2sActivityParams != null - ? s2sActivityParams - : activityParams(MODULE_TYPE_BIDDER, bidderRequest.bidderCode) - ); - const [tid, tidSource] = getTid(bidderRequest.bidderCode, bidderRequest.auctionId, bidderOrtb2[bidderRequest.bidderCode]?.source?.tid ?? ortb2.source?.tid); - const fpd = Object.freeze(redact.ortb2(mergeDeep( - {}, - ortb2, - bidderOrtb2[bidderRequest.bidderCode], - { - source: { - tid, - ext: {tidSource} - } - } - ))); + const [fpd, redact] = mergeBidderFpd(bidderRequest.auctionId, bidderRequest.bidderCode, s2sActivityParams); bidderRequest.ortb2 = fpd; bidderRequest.bids = bidderRequest.bids.map((bid) => { bid.ortb2 = fpd; @@ -578,7 +608,7 @@ const adapterManager = { _s2sConfigs.forEach(s2sConfig => { const s2sParams = s2sActivityParams(s2sConfig); if (s2sConfig && s2sConfig.enabled && dep.isAllowed(ACTIVITY_FETCH_BIDS, s2sParams)) { - const {adUnits: adUnitsS2SCopy, hasModuleBids} = getAdUnitCopyForPrebidServer(adUnits, s2sConfig); + const { adUnits: adUnitsS2SCopy, hasModuleBids } = getAdUnitCopyForPrebidServer(adUnits, s2sConfig); // uniquePbsTid is so we know which server to send which bids to during the callBids function const uniquePbsTid = generateUUID(); @@ -723,7 +753,7 @@ const adapterManager = { const uniqueServerRequests = serverBidderRequests.filter(serverBidRequest => serverBidRequest.uniquePbsTid === uniquePbsTid); if (s2sAdapter) { - const s2sBidRequest = {'ad_units': adUnitsS2SCopy, s2sConfig, ortb2Fragments, requestBidsTimeout}; + const s2sBidRequest = { 'ad_units': adUnitsS2SCopy, s2sConfig, ortb2Fragments, requestBidsTimeout }; if (s2sBidRequest.ad_units.length) { const doneCbs = uniqueServerRequests.map(bidRequest => { bidRequest.start = timestamp(); @@ -787,13 +817,13 @@ const adapterManager = { ) ); } catch (e) { - logError(`${bidderRequest.bidderCode} Bid Adapter emitted an uncaught error when parsing their bidRequest`, {e, bidRequest: bidderRequest}); + logError(`${bidderRequest.bidderCode} Bid Adapter emitted an uncaught error when parsing their bidRequest`, { e, bidRequest: bidderRequest }); adapterDone(); } }) }, videoAdapters: [], - registerBidAdapter(bidAdapter, bidderCode, {supportedMediaTypes = []} = {}) { + registerBidAdapter(bidAdapter, bidderCode, { supportedMediaTypes = [] } = {}) { if (bidAdapter && bidderCode) { if (typeof bidAdapter.callBids === 'function') { _bidderRegistry[bidderCode] = bidAdapter; @@ -874,7 +904,7 @@ const adapterManager = { } return code; }, - registerAnalyticsAdapter

({adapter, code, gvlid}: { + registerAnalyticsAdapter

({ adapter, code, gvlid }: { adapter: AnalyticsAdapter

, code: P, gvlid?: number @@ -904,7 +934,7 @@ const adapterManager = { config.forEach(adapterConfig => { const entry = _analyticsRegistry[adapterConfig.provider]; if (entry && entry.adapter) { - if (dep.isAllowed(ACTIVITY_REPORT_ANALYTICS, activityParams(MODULE_TYPE_ANALYTICS, adapterConfig.provider, {[ACTIVITY_PARAM_ANL_CONFIG]: adapterConfig}))) { + if (dep.isAllowed(ACTIVITY_REPORT_ANALYTICS, activityParams(MODULE_TYPE_ANALYTICS, adapterConfig.provider, { [ACTIVITY_PARAM_ANL_CONFIG]: adapterConfig }))) { entry.adapter.enableAnalytics(adapterConfig); } } else { diff --git a/src/adapters/bidderFactory.ts b/src/adapters/bidderFactory.ts index 60f21964f88..0376e3a0607 100644 --- a/src/adapters/bidderFactory.ts +++ b/src/adapters/bidderFactory.ts @@ -4,12 +4,12 @@ import adapterManager, { type BidRequest, type ClientBidderRequest } from '../adapterManager.js'; -import {config} from '../config.js'; -import {BannerBid, Bid, BidResponse, createBid} from '../bidfactory.js'; -import {type SyncType, userSync} from '../userSync.js'; -import {nativeBidIsValid} from '../native.js'; -import {isValidVideoBid} from '../video.js'; -import {EVENTS, REJECTION_REASON, DEBUG_MODE} from '../constants.js'; +import { config } from '../config.js'; +import { BannerBid, Bid, BidResponse, createBid } from '../bidfactory.js'; +import { type SyncType, userSync } from '../userSync.js'; +import { nativeBidIsValid } from '../native.js'; +import { isValidVideoBid } from '../video.js'; +import { EVENTS, REJECTION_REASON, DEBUG_MODE } from '../constants.js'; import * as events from '../events.js'; import { @@ -28,20 +28,20 @@ import { getParameterByName, debugTurnedOn } from '../utils.js'; -import {hook} from '../hook.js'; -import {auctionManager} from '../auctionManager.js'; -import {bidderSettings} from '../bidderSettings.js'; -import {useMetrics} from '../utils/perfMetrics.js'; -import {isActivityAllowed} from '../activities/rules.js'; -import {activityParams} from '../activities/activityParams.js'; -import {MODULE_TYPE_BIDDER} from '../activities/modules.js'; -import {ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD} from '../activities/activities.js'; -import type {AnyFunction, Wraps} from "../types/functions.d.ts"; -import type {BidderCode, StorageDisclosure} from "../types/common.d.ts"; -import type {Ajax, AjaxOptions, XHR} from "../ajax.ts"; -import type {AddBidResponse} from "../auction.ts"; -import type {MediaType} from "../mediaTypes.ts"; -import {CONSENT_GDPR, CONSENT_GPP, CONSENT_USP, type ConsentData} from "../consentHandler.ts"; +import { hook } from '../hook.js'; +import { auctionManager } from '../auctionManager.js'; +import { bidderSettings } from '../bidderSettings.js'; +import { useMetrics } from '../utils/perfMetrics.js'; +import { isActivityAllowed } from '../activities/rules.js'; +import { activityParams } from '../activities/activityParams.js'; +import { MODULE_TYPE_BIDDER } from '../activities/modules.js'; +import { ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD } from '../activities/activities.js'; +import type { AnyFunction, Wraps } from "../types/functions.d.ts"; +import type { BidderCode, StorageDisclosure } from "../types/common.d.ts"; +import type { Ajax, AjaxOptions, XHR } from "../ajax.ts"; +import type { AddBidResponse } from "../auction.ts"; +import type { MediaType } from "../mediaTypes.ts"; +import { CONSENT_GDPR, CONSENT_GPP, CONSENT_USP, type ConsentData } from "../consentHandler.ts"; /** * This file aims to support Adapters during the Prebid 0.x -> 1.x transition. @@ -197,7 +197,7 @@ export function registerBidder(spec: BidderSpec) { } } -export const guardTids: any = memoize(({bidderCode}) => { +export const guardTids: any = memoize(({ bidderCode }) => { const tidsAllowed = isActivityAllowed(ACTIVITY_TRANSMIT_TID, activityParams(MODULE_TYPE_BIDDER, bidderCode)); function get(target, prop, receiver) { if (TIDS.hasOwnProperty(prop)) { @@ -215,7 +215,7 @@ export const guardTids: any = memoize(({bidderCode}) => { }); return proxy; } - const bidRequest = memoize((br) => privateAccessProxy(br, {get}), (arg) => arg.bidId); + const bidRequest = memoize((br) => privateAccessProxy(br, { get }), (arg) => arg.bidId); /** * Return a view on bidd(er) requests where auctionId/transactionId are nulled if the bidder is not allowed `transmitTid`. * @@ -334,7 +334,7 @@ export function newBidder(spec: BidderSpec) { } adapterManager.callBidderError(spec.code, error, bidderRequest) events.emit(EVENTS.BIDDER_ERROR, { error, bidderRequest }); - logError(`Server call for ${spec.code} failed: ${errorMessage} ${error.status}. Continuing without bids.`, {bidRequests: validBidRequests}); + logError(`Server call for ${spec.code} failed: ${errorMessage} ${error.status}. Continuing without bids.`, { bidRequests: validBidRequests }); }, onBid: (bidResponse) => { const bidRequest = bidRequestMap[bidResponse.requestId]; @@ -407,7 +407,7 @@ export const processBidderRequests = hook('async', function, ajax: Ajax, wrapCallback: (fn: T) => Wraps, - {onRequest, onResponse, onPaapi, onError, onBid, onCompletion}: { + { onRequest, onResponse, onPaapi, onError, onBid, onCompletion }: { /** * invoked once for each HTTP request built by the adapter - with the raw request */ @@ -629,7 +629,7 @@ declare module '../bidfactory' { } // check that the bid has a width and height set -function validBidSize(adUnitCode, bid: BannerBid, {index = auctionManager.index} = {}) { +function validBidSize(adUnitCode, bid: BannerBid, { index = auctionManager.index } = {}) { if ((bid.width || parseInt(bid.width, 10) === 0) && (bid.height || parseInt(bid.height, 10) === 0)) { bid.width = parseInt(bid.width, 10); bid.height = parseInt(bid.height, 10); @@ -651,7 +651,7 @@ function validBidSize(adUnitCode, bid: BannerBid, {index = auctionManager.index} // if a banner impression has one valid size, we assign that size to any bid // response that does not explicitly set width or height if (parsedSizes.length === 1) { - const [ width, height ] = parsedSizes[0].split('x'); + const [width, height] = parsedSizes[0].split('x'); bid.width = parseInt(width, 10); bid.height = parseInt(height, 10); return true; @@ -661,7 +661,7 @@ function validBidSize(adUnitCode, bid: BannerBid, {index = auctionManager.index} } // Validate the arguments sent to us by the adapter. If this returns false, the bid should be totally ignored. -export function isValid(adUnitCode: string, bid: Bid, {index = auctionManager.index} = {}) { +export function isValid(adUnitCode: string, bid: Bid, { index = auctionManager.index } = {}) { function hasValidKeys() { const bidKeys = Object.keys(bid); return COMMON_BID_RESPONSE_KEYS.every(key => bidKeys.includes(key) && ![undefined, null].includes(bid[key])); @@ -686,15 +686,15 @@ export function isValid(adUnitCode: string, bid: Bid, {index = auctionManager.in return false; } - if (FEATURES.NATIVE && bid.mediaType === 'native' && !nativeBidIsValid(bid, {index})) { + if (FEATURES.NATIVE && bid.mediaType === 'native' && !nativeBidIsValid(bid, { index })) { logError(errorMessage('Native bid missing some required properties.')); return false; } - if (FEATURES.VIDEO && bid.mediaType === 'video' && !isValidVideoBid(bid, {index})) { + if (FEATURES.VIDEO && bid.mediaType === 'video' && !isValidVideoBid(bid, { index })) { logError(errorMessage(`Video bid does not have required vastUrl or renderer property`)); return false; } - if (bid.mediaType === 'banner' && !validBidSize(adUnitCode, bid, {index})) { + if (bid.mediaType === 'banner' && !validBidSize(adUnitCode, bid, { index })) { logError(errorMessage(`Banner bids require a width and height`)); return false; } diff --git a/src/adloader.js b/src/adloader.js index 098b78c211b..71f6698141e 100644 --- a/src/adloader.js +++ b/src/adloader.js @@ -5,45 +5,6 @@ import { isActivityAllowed } from './activities/rules.js'; import { insertElement, logError, logWarn, setScriptAttributes } from './utils.js'; const _requestCache = new WeakMap(); -// The below list contains modules or vendors whom Prebid allows to load external JS. -const _approvedLoadExternalJSList = [ - // Prebid maintained modules: - 'debugging', - 'outstream', - // RTD modules: - 'aaxBlockmeter', - 'adagio', - 'adloox', - 'arcspan', - 'airgrid', - 'browsi', - 'brandmetrics', - 'clean.io', - 'humansecurityMalvDefense', - 'humansecurity', - 'confiant', - 'contxtful', - 'hadron', - 'mediafilter', - 'medianet', - 'azerionedge', - 'a1Media', - 'geoedge', - 'qortex', - 'dynamicAdBoost', - '51Degrees', - 'symitridap', - 'wurfl', - 'nodalsAi', - 'anonymised', - 'optable', - 'oftmedia', - // UserId Submodules - 'justtag', - 'tncId', - 'ftrackId', - 'id5', -]; /** * Loads external javascript. Can only be used if external JS is approved by Prebid. See https://github.com/prebid/prebid-js-external-js-template#policy @@ -64,10 +25,7 @@ export function loadExternalScript(url, moduleType, moduleCode, callback, doc, a logError('cannot load external script without url and moduleCode'); return; } - if (!_approvedLoadExternalJSList.includes(moduleCode)) { - logError(`${moduleCode} not whitelisted for loading external JavaScript`); - return; - } + if (!doc) { doc = document; // provide a "valid" key for the WeakMap } diff --git a/src/adserver.js b/src/adserver.js index db7aaaa1dc8..cd44b725e2f 100644 --- a/src/adserver.js +++ b/src/adserver.js @@ -1,4 +1,4 @@ -import {hook} from './hook.js'; +import { hook } from './hook.js'; /** * return the GAM PPID, if available (eid for the userID configured with `userSync.ppidSource`) diff --git a/src/ajax.ts b/src/ajax.ts index 58ed89b6e83..986369c7a0f 100644 --- a/src/ajax.ts +++ b/src/ajax.ts @@ -1,9 +1,9 @@ import { ACTIVITY_ACCESS_REQUEST_CREDENTIALS } from './activities/activities.js'; import { activityParams } from './activities/activityParams.js'; import { isActivityAllowed } from './activities/rules.js'; -import {config} from './config.js'; +import { config } from './config.js'; import { hook } from './hook.js'; -import {buildUrl, hasDeviceAccess, logError, parseUrl} from './utils.js'; +import { buildUrl, hasDeviceAccess, logError, parseUrl } from './utils.js'; export const dep = { fetch: window.fetch.bind(window), @@ -118,12 +118,12 @@ export function toFetchRequest(url, data, options: AjaxOptions = {}) { * `request` is invoked at the beginning of each request, and `done` at the end; both are passed its origin. * */ -export function fetcherFactory(timeout = 3000, {request, done}: any = {}, moduleType?: string, moduleName?: string): typeof window['fetch'] { +export function fetcherFactory(timeout = 3000, { request, done }: any = {}, moduleType?: string, moduleName?: string): typeof window['fetch'] { let fetcher = (resource, options) => { let to; if (timeout != null && options?.signal == null && !config.getConfig('disableAjaxTimeout')) { to = dep.timeout(timeout, resource); - options = Object.assign({signal: to.signal}, options); + options = Object.assign({ signal: to.signal }, options); } processRequestOptions(options, moduleType, moduleName); @@ -147,7 +147,7 @@ export function fetcherFactory(timeout = 3000, {request, done}: any = {}, module export type XHR = ReturnType; -function toXHR({status, statusText = '', headers, url}: { +function toXHR({ status, statusText = '', headers, url }: { status: number; statusText?: string; headers?: Response['headers']; @@ -179,7 +179,7 @@ function toXHR({status, statusText = '', headers, url}: { }, getResponseHeader: (header) => headers?.has(header) ? headers.get(header) : null, toJSON() { - return Object.assign({responseXML: getXML()}, this) + return Object.assign({ responseXML: getXML() }, this) }, timedOut: false } @@ -189,7 +189,7 @@ function toXHR({status, statusText = '', headers, url}: { * attach legacy `ajax` callbacks to a fetch promise. */ export function attachCallbacks(fetchPm: Promise, callback: AjaxCallback) { - const {success, error} = typeof callback === 'object' && callback != null ? callback : { + const { success, error } = typeof callback === 'object' && callback != null ? callback : { success: typeof callback === 'function' ? callback : () => null, error: (e, x) => logError('Network error', e, x) }; @@ -200,8 +200,8 @@ export function attachCallbacks(fetchPm: Promise, callback: AjaxCallba const xhr = toXHR(response, responseText); response.ok || response.status === 304 ? success(responseText, xhr) : error(response.statusText, xhr); }, (reason) => error('', Object.assign( - toXHR({status: 0}, ''), - {reason, timedOut: reason?.name === 'AbortError'})) + toXHR({ status: 0 }, ''), + { reason, timedOut: reason?.name === 'AbortError' })) ); } @@ -209,8 +209,8 @@ export type AjaxSuccessCallback = (responseText: string, xhr: XHR) => void; export type AjaxErrorCallback = (statusText: string, xhr: XHR) => void; export type AjaxCallback = AjaxSuccessCallback | { success?: AjaxErrorCallback; error?: AjaxSuccessCallback }; -export function ajaxBuilder(timeout = 3000, {request, done} = {} as any, moduleType?: string, moduleName?: string) { - const fetcher = fetcherFactory(timeout, {request, done}, moduleType, moduleName); +export function ajaxBuilder(timeout = 3000, { request, done } = {} as any, moduleType?: string, moduleName?: string) { + const fetcher = fetcherFactory(timeout, { request, done }, moduleType, moduleName); return function (url: string, callback?: AjaxCallback, data?: unknown, options: AjaxOptions = {}) { attachCallbacks(fetcher(toFetchRequest(url, data, options)), callback); }; diff --git a/src/auction.ts b/src/auction.ts index 97984dae443..8130d37e590 100644 --- a/src/auction.ts +++ b/src/auction.ts @@ -10,32 +10,35 @@ import { parseUrl, timestamp } from './utils.js'; -import {getPriceBucketString} from './cpmBucketManager.js'; -import {isNativeResponse, setNativeResponseProperties} from './native.js'; -import {batchAndStore, storeLocally} from './videoCache.js'; -import {Renderer} from './Renderer.js'; -import {config} from './config.js'; -import {userSync} from './userSync.js'; -import {hook, ignoreCallbackArg} from './hook.js'; -import {OUTSTREAM} from './video.js'; -import {AUDIO, VIDEO} from './mediaTypes.js'; -import {auctionManager} from './auctionManager.js'; -import {bidderSettings} from './bidderSettings.js'; +import { getPriceBucketString } from './cpmBucketManager.js'; +import { isNativeResponse, setNativeResponseProperties } from './native.js'; +import { batchAndStore, storeLocally } from './videoCache.js'; +import { Renderer } from './Renderer.js'; +import { config } from './config.js'; +import { userSync } from './userSync.js'; +import { hook, ignoreCallbackArg } from './hook.js'; +import { OUTSTREAM } from './video.js'; +import { AUDIO, VIDEO } from './mediaTypes.js'; +import { auctionManager } from './auctionManager.js'; +import { bidderSettings } from './bidderSettings.js'; import * as events from './events.js'; -import adapterManager, {type BidderRequest, type BidRequest} from './adapterManager.js'; -import {EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS} from './constants.js'; -import {defer, PbPromise} from './utils/promise.js'; -import {type Metrics, useMetrics} from './utils/perfMetrics.js'; -import {adjustCpm} from './utils/cpm.js'; -import {getGlobal} from './prebidGlobal.js'; -import {ttlCollection} from './utils/ttlCollection.js'; -import {getMinBidCacheTTL, onMinBidCacheTTLChange} from './bidTTL.js'; -import type {Bid, BidResponse} from "./bidfactory.ts"; -import type {AdUnitCode, BidderCode, Identifier, ORTBFragments} from './types/common.d.ts'; -import type {TargetingMap} from "./targeting.ts"; -import type {AdUnit} from "./adUnits.ts"; -import type {MediaType} from "./mediaTypes.ts"; -import type {VideoContext} from "./video.ts"; +import adapterManager, { activityParams, type BidderRequest, type BidRequest } from './adapterManager.js'; +import { EVENTS, GRANULARITY_OPTIONS, JSON_MAPPING, REJECTION_REASON, S2S, TARGETING_KEYS } from './constants.js'; +import { defer, PbPromise } from './utils/promise.js'; +import { type Metrics, useMetrics } from './utils/perfMetrics.js'; +import { adjustCpm } from './utils/cpm.js'; +import { getGlobal } from './prebidGlobal.js'; +import { ttlCollection } from './utils/ttlCollection.js'; +import { getMinBidCacheTTL, onMinBidCacheTTLChange } from './bidTTL.js'; +import type { Bid, BidResponse } from "./bidfactory.ts"; +import type { AdUnitCode, BidderCode, Identifier, ORTBFragments } from './types/common.d.ts'; +import type { TargetingMap } from "./targeting.ts"; +import type { AdUnit } from "./adUnits.ts"; +import type { MediaType } from "./mediaTypes.ts"; +import type { VideoContext } from "./video.ts"; +import { isActivityAllowed } from './activities/rules.js'; +import { ACTIVITY_ADD_BID_RESPONSE } from './activities/activities.js'; +import { MODULE_TYPE_BIDDER } from './activities/modules.ts'; const { syncUsers } = userSync; @@ -165,13 +168,13 @@ declare module './config' { auctionOptions?: AuctionOptionsConfig; priceGranularity?: (typeof GRANULARITY_OPTIONS)[keyof typeof GRANULARITY_OPTIONS]; customPriceBucket?: PriceBucketConfig; - mediaTypePriceGranularity?: {[K in MediaType]?: PriceBucketConfig} & {[K in VideoContext as `${typeof VIDEO}-${K}`]?: PriceBucketConfig}; + mediaTypePriceGranularity?: { [K in MediaType]?: PriceBucketConfig } & { [K in VideoContext as `${typeof VIDEO}-${K}`]?: PriceBucketConfig }; } } export const beforeInitAuction = hook('sync', (auction) => {}) -export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, auctionId, ortb2Fragments, metrics}: AuctionOptions) { +export function newAuction({ adUnits, adUnitCodes, callback, cbTimeout, labels, auctionId, ortb2Fragments, metrics }: AuctionOptions) { metrics = useMetrics(metrics); const _adUnits = adUnits; const _labels = labels; @@ -252,7 +255,7 @@ export function newAuction({adUnits, adUnitCodes, callback, cbTimeout, labels, a done.resolve(); events.emit(EVENTS.AUCTION_END, getProperties()); - bidsBackCallback(_adUnits, function () { + bidsBackCallback(_adUnits, auctionId, function () { try { if (_callback != null) { const bids = _bidsReceived.toArray() @@ -469,7 +472,13 @@ declare module './hook' { */ export const addBidResponse = ignoreCallbackArg(hook('async', function(adUnitCode: string, bid: Partial, reject: (reason: (typeof REJECTION_REASON)[keyof typeof REJECTION_REASON]) => void): void { if (!isValidPrice(bid)) { - reject(REJECTION_REASON.PRICE_TOO_HIGH) + reject(REJECTION_REASON.PRICE_TOO_HIGH); + } else if (!isActivityAllowed(ACTIVITY_ADD_BID_RESPONSE, activityParams(MODULE_TYPE_BIDDER, bid.bidder || bid.bidderCode, { + bid, + ortb2: auctionManager.index.getOrtb2(bid), + adUnit: auctionManager.index.getAdUnit(bid), + }))) { + reject(REJECTION_REASON.BIDDER_DISALLOWED); } else { this.dispatch.call(null, adUnitCode, bid); } @@ -487,7 +496,7 @@ export const addBidderRequests = hook('sync', function(bidderRequests) { this.dispatch.call(this.context, bidderRequests); }, 'addBidderRequests'); -export const bidsBackCallback = hook('async', function (adUnits, callback) { +export const bidsBackCallback = hook('async', function (adUnits, auctionId, callback) { if (callback) { callback(); } @@ -498,7 +507,7 @@ export type AddBidResponse = { reject(adUnitCode: AdUnitCode, bid: BidResponse, reason: typeof REJECTION_REASON[keyof typeof REJECTION_REASON]) : void; } -export function auctionCallbacks(auctionDone, auctionInstance, {index = auctionManager.index} = {}) { +export function auctionCallbacks(auctionDone, auctionInstance, { index = auctionManager.index } = {}) { let outstandingBidsAdded = 0; let allAdapterCalledDone = false; const bidderRequestsDone = new Set(); @@ -608,7 +617,7 @@ export function addBidToAuction(auctionInstance, bidResponse: Bid) { } // Video bids may fail if the cache is down, or there's trouble on the network. -function tryAddVideoAudioBid(auctionInstance, bidResponse, afterBidAdded, {index = auctionManager.index} = {}) { +function tryAddVideoAudioBid(auctionInstance, bidResponse, afterBidAdded, { index = auctionManager.index } = {}) { let addBid = true; const videoMediaType = index.getMediaTypes({ @@ -724,7 +733,7 @@ declare module './bidfactory' { /** * Add timing properties to a bid response */ -function addBidTimingProperties(bidResponse: Partial, {index = auctionManager.index} = {}) { +function addBidTimingProperties(bidResponse: Partial, { index = auctionManager.index } = {}) { const bidderRequest = index.getBidderRequest(bidResponse); const start = (bidderRequest && bidderRequest.start) || bidResponse.requestTimestamp; @@ -738,10 +747,10 @@ function addBidTimingProperties(bidResponse: Partial, {index = auctionManag /** * Augment `bidResponse` with properties that are common across all bids - including rejected bids. */ -function addCommonResponseProperties(bidResponse: Partial, adUnitCode: string, {index = auctionManager.index} = {}) { +function addCommonResponseProperties(bidResponse: Partial, adUnitCode: string, { index = auctionManager.index } = {}) { const adUnit = index.getAdUnit(bidResponse); - addBidTimingProperties(bidResponse, {index}) + addBidTimingProperties(bidResponse, { index }) Object.assign(bidResponse, { cpm: parseFloat(bidResponse.cpm) || 0, @@ -757,7 +766,7 @@ function addCommonResponseProperties(bidResponse: Partial, adUnitCode: stri /** * Add additional bid response properties that are universal for all _accepted_ bids. */ -function getPreparedBidForAuction(bid: Partial, {index = auctionManager.index} = {}): Bid { +function getPreparedBidForAuction(bid: Partial, { index = auctionManager.index } = {}): Bid { // Let listeners know that now is the time to adjust the bid, if they want to. // // CAREFUL: Publishers rely on certain bid properties to be available (like cpm), @@ -839,7 +848,7 @@ export function getMediaTypeGranularity(mediaType, mediaTypes, mediaTypePriceGra * @param {object} obj.index * @returns {string} granularity */ -export const getPriceGranularity = (bid, {index = auctionManager.index} = {}) => { +export const getPriceGranularity = (bid, { index = auctionManager.index } = {}) => { // Use the config value 'mediaTypeGranularity' if it has been set for mediaType, else use 'priceGranularity' const mediaTypeGranularity = getMediaTypeGranularity(bid.mediaType, index.getMediaTypes(bid), config.getConfig('mediaTypePriceGranularity')); const granularity = (typeof bid.mediaType === 'string' && mediaTypeGranularity) ? ((typeof mediaTypeGranularity === 'string') ? mediaTypeGranularity : 'custom') : config.getConfig('priceGranularity'); @@ -1044,7 +1053,7 @@ export function getStandardBidderSettings(mediaType, bidderCode) { return standardSettings; } -export function getKeyValueTargetingPairs(bidderCode, custBidObj: Bid, {index = auctionManager.index} = {}) { +export function getKeyValueTargetingPairs(bidderCode, custBidObj: Bid, { index = auctionManager.index } = {}) { if (!custBidObj) { return {}; } diff --git a/src/auctionIndex.js b/src/auctionIndex.js index 0bf0fb88943..58243aa4f49 100644 --- a/src/auctionIndex.js +++ b/src/auctionIndex.js @@ -11,6 +11,7 @@ * Bid responses are not guaranteed to have a corresponding request. * @property {function({ requestId?: string }): *} getBidRequest Returns bidRequest object for requestId. * Bid responses are not guaranteed to have a corresponding request. + * @property {function} getOrtb2 Returns ortb2 object for bid */ /** @@ -19,33 +20,33 @@ */ export function AuctionIndex(getAuctions) { Object.assign(this, { - getAuction({auctionId}) { + getAuction({ auctionId }) { if (auctionId != null) { return getAuctions() .find(auction => auction.getAuctionId() === auctionId); } }, - getAdUnit({adUnitId}) { + getAdUnit({ adUnitId }) { if (adUnitId != null) { return getAuctions() .flatMap(a => a.getAdUnits()) .find(au => au.adUnitId === adUnitId); } }, - getMediaTypes({adUnitId, requestId}) { + getMediaTypes({ adUnitId, requestId }) { if (requestId != null) { - const req = this.getBidRequest({requestId}); + const req = this.getBidRequest({ requestId }); if (req != null && (adUnitId == null || req.adUnitId === adUnitId)) { return req.mediaTypes; } } else if (adUnitId != null) { - const au = this.getAdUnit({adUnitId}); + const au = this.getAdUnit({ adUnitId }); if (au != null) { return au.mediaTypes; } } }, - getBidderRequest({requestId, bidderRequestId}) { + getBidderRequest({ requestId, bidderRequestId }) { if (requestId != null || bidderRequestId != null) { let bers = getAuctions().flatMap(a => a.getBidRequests()); if (bidderRequestId != null) { @@ -58,7 +59,7 @@ export function AuctionIndex(getAuctions) { } } }, - getBidRequest({requestId}) { + getBidRequest({ requestId }) { if (requestId != null) { return getAuctions() .flatMap(a => a.getBidRequests()) diff --git a/src/auctionManager.js b/src/auctionManager.js index 0e0d8af8f9c..40395d95f28 100644 --- a/src/auctionManager.js +++ b/src/auctionManager.js @@ -27,11 +27,11 @@ import { uniques, logWarn } from './utils.js'; import { newAuction, getStandardBidderSettings, AUCTION_COMPLETED } from './auction.js'; -import {AuctionIndex} from './auctionIndex.js'; +import { AuctionIndex } from './auctionIndex.js'; import { BID_STATUS, JSON_MAPPING } from './constants.js'; -import {useMetrics} from './utils/perfMetrics.js'; -import {ttlCollection} from './utils/ttlCollection.js'; -import {getMinBidCacheTTL, onMinBidCacheTTLChange} from './bidTTL.js'; +import { useMetrics } from './utils/perfMetrics.js'; +import { ttlCollection } from './utils/ttlCollection.js'; +import { getMinBidCacheTTL, onMinBidCacheTTLChange } from './bidTTL.js'; /** * Creates new instance of auctionManager. There will only be one instance of auctionManager but @@ -89,7 +89,7 @@ export function newAuctionManager() { getAdUnitCodes: { post: uniques, } - }).forEach(([mgrMethod, {name = mgrMethod, pre, post}]) => { + }).forEach(([mgrMethod, { name = mgrMethod, pre, post }]) => { const mapper = pre == null ? (auction) => auction[name]() : (auction) => pre(auction) ? auction[name]() : []; diff --git a/src/audio.ts b/src/audio.ts index 998531f1bf9..a2f8af10c52 100644 --- a/src/audio.ts +++ b/src/audio.ts @@ -1,34 +1,34 @@ -import {isArrayOfNums, isInteger, logError} from './utils.js'; -import {config} from './config.js'; -import {hook} from './hook.js'; -import {auctionManager} from './auctionManager.js'; -import type {AudioBid} from "./bidfactory.ts"; -import {type BaseMediaType} from "./mediaTypes.ts"; -import type {ORTBImp} from "./types/ortb/request"; -import type {AdUnitDefinition} from "./adUnits.ts"; -import {getGlobalVarName} from "./buildOptions.ts"; +import { isArrayOfNums, isInteger, logError } from './utils.js'; +import { config } from './config.js'; +import { hook } from './hook.js'; +import { auctionManager } from './auctionManager.js'; +import type { AudioBid } from "./bidfactory.ts"; +import { type BaseMediaType } from "./mediaTypes.ts"; +import type { ORTBImp } from "./types/ortb/request"; +import type { AdUnitDefinition } from "./adUnits.ts"; +import { getGlobalVarName } from "./buildOptions.ts"; export const OUTSTREAM = 'outstream'; export const INSTREAM = 'instream'; const ORTB_PARAMS = [ - [ 'mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string') ], - [ 'minduration', isInteger ], - [ 'maxduration', isInteger ], - [ 'startdelay', isInteger ], - [ 'maxseq', isInteger ], - [ 'poddur', isInteger ], - [ 'protocols', isArrayOfNums ], - [ 'battr', isArrayOfNums ], - [ 'maxextended', isInteger ], - [ 'minbitrate', isInteger ], - [ 'maxbitrate', isInteger ], - [ 'delivery', isArrayOfNums ], - [ 'api', isArrayOfNums ], - [ 'companiontype', isArrayOfNums ], - [ 'feed', isInteger ], - [ 'stitched', isInteger ], - [ 'nvol', isInteger ], + ['mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string')], + ['minduration', isInteger], + ['maxduration', isInteger], + ['startdelay', isInteger], + ['maxseq', isInteger], + ['poddur', isInteger], + ['protocols', isArrayOfNums], + ['battr', isArrayOfNums], + ['maxextended', isInteger], + ['minbitrate', isInteger], + ['maxbitrate', isInteger], + ['delivery', isArrayOfNums], + ['api', isArrayOfNums], + ['companiontype', isArrayOfNums], + ['feed', isInteger], + ['stitched', isInteger], + ['nvol', isInteger], ] as const; /** @@ -49,7 +49,7 @@ export function fillAudioDefaults(adUnit: AdUnitDefinition) {} /** * Validate that the assets required for audio context are present on the bid */ -export function isValidAudioBid(bid: AudioBid, {index = auctionManager.index} = {}): boolean { +export function isValidAudioBid(bid: AudioBid, { index = auctionManager.index } = {}): boolean { const audioMediaType = index.getMediaTypes(bid)?.audio; const context = audioMediaType && audioMediaType?.context; const useCacheKey = audioMediaType && audioMediaType?.useCacheKey; diff --git a/src/banner.ts b/src/banner.ts index 5b9520348aa..0f69254028b 100644 --- a/src/banner.ts +++ b/src/banner.ts @@ -1,21 +1,21 @@ import { isArrayOfNums, isInteger, isStr } from './utils.js'; -import type {Size} from "./types/common.d.ts"; -import type {ORTBImp} from "./types/ortb/request.d.ts"; -import type {BaseMediaType} from "./mediaTypes.ts"; +import type { Size } from "./types/common.d.ts"; +import type { ORTBImp } from "./types/ortb/request.d.ts"; +import type { BaseMediaType } from "./mediaTypes.ts"; const ORTB_PARAMS = [ - [ 'format', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'object') ], - [ 'w', isInteger ], - [ 'h', isInteger ], - [ 'btype', isArrayOfNums ], - [ 'battr', isArrayOfNums ], - [ 'pos', isInteger ], - [ 'mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string') ], - [ 'topframe', value => [1, 0].includes(value) ], - [ 'expdir', isArrayOfNums ], - [ 'api', isArrayOfNums ], - [ 'id', isStr ], - [ 'vcm', value => [1, 0].includes(value) ] + ['format', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'object')], + ['w', isInteger], + ['h', isInteger], + ['btype', isArrayOfNums], + ['battr', isArrayOfNums], + ['pos', isInteger], + ['mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string')], + ['topframe', value => [1, 0].includes(value)], + ['expdir', isArrayOfNums], + ['api', isArrayOfNums], + ['id', isStr], + ['vcm', value => [1, 0].includes(value)] ] as const; /** diff --git a/src/bidTTL.ts b/src/bidTTL.ts index c6e5db37eb8..2af2986311c 100644 --- a/src/bidTTL.ts +++ b/src/bidTTL.ts @@ -1,5 +1,5 @@ -import {config} from './config.js'; -import {logError} from './utils.js'; +import { config } from './config.js'; +import { logError } from './utils.js'; const CACHE_TTL_SETTING = 'minBidCacheTTL'; let TTL_BUFFER = 1; let minCacheTTL = null; diff --git a/src/bidderSettings.ts b/src/bidderSettings.ts index 0da7be81b0c..c9d68cdddf7 100644 --- a/src/bidderSettings.ts +++ b/src/bidderSettings.ts @@ -1,10 +1,10 @@ -import {deepAccess, mergeDeep} from './utils.js'; -import {getGlobal} from './prebidGlobal.js'; +import { deepAccess, mergeDeep } from './utils.js'; +import { getGlobal } from './prebidGlobal.js'; import { JSON_MAPPING } from './constants.js'; -import type {BidderCode} from "./types/common"; -import type {BidRequest} from "./adapterManager.ts"; -import type {Bid} from "./bidfactory.ts"; -import type {StorageType} from "./storageManager.ts"; +import type { BidderCode } from "./types/common"; +import type { BidRequest } from "./adapterManager.ts"; +import type { Bid } from "./bidfactory.ts"; +import type { StorageType } from "./storageManager.ts"; // eslint-disable-next-line @typescript-eslint/no-unused-vars export interface BidderSettings { diff --git a/src/bidfactory.ts b/src/bidfactory.ts index b87d3b14a26..576e97eb2a8 100644 --- a/src/bidfactory.ts +++ b/src/bidfactory.ts @@ -1,12 +1,12 @@ -import {getUniqueIdentifierStr} from './utils.js'; -import type {BidderCode, BidSource, ContextIdentifiers, Currency, Identifier} from "./types/common.d.ts"; -import {MediaType} from "./mediaTypes.ts"; -import type {DSAResponse} from "./types/ortb/ext/dsa.d.ts"; -import type {EventTrackerResponse} from "./types/ortb/native.d.ts"; -import {Metrics} from "./utils/perfMetrics.ts"; -import {Renderer} from './Renderer.js'; -import {type BID_STATUS} from "./constants.ts"; -import type {DemandChain} from "./types/ortb/ext/dchain.d.ts"; +import { getUniqueIdentifierStr } from './utils.js'; +import type { BidderCode, BidSource, ContextIdentifiers, Currency, Identifier } from "./types/common.d.ts"; +import { MediaType } from "./mediaTypes.ts"; +import type { DSAResponse } from "./types/ortb/ext/dsa.d.ts"; +import type { EventTrackerResponse } from "./types/ortb/native.d.ts"; +import { Metrics } from "./utils/perfMetrics.ts"; +import { Renderer } from './Renderer.js'; +import { type BID_STATUS } from "./constants.ts"; +import type { DemandChain } from "./types/ortb/ext/dchain.d.ts"; type BidIdentifiers = ContextIdentifiers & { src: BidSource; @@ -135,7 +135,6 @@ export interface BaseBid extends ContextIdentifiers, Required = {[K in keyof T]?: undefined}; +type NullProps = { [K in keyof T]?: undefined }; type NullBid = NullProps<_BannerBid> & NullProps<_VideoBid> & NullProps<_NativeBid>; type ExtendBid = B & Omit; @@ -194,7 +193,7 @@ export type AudioBid = VideoBid; export type Bid = BannerBid | VideoBid | NativeBid | AudioBid; // eslint-disable-next-line @typescript-eslint/no-redeclare -function Bid({src = 'client', bidder = '', bidId, transactionId, adUnitId, auctionId}: Partial = {}) { +function Bid({ src = 'client', bidder = '', bidId, transactionId, adUnitId, auctionId }: Partial = {}) { var _bidSrc = src; Object.assign(this, { diff --git a/src/config.ts b/src/config.ts index 96f0427ea07..827856df0f0 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,7 @@ * Module for getting and setting Prebid configuration. */ -import {isValidPriceConfig} from './cpmBucketManager.js'; +import { isValidPriceConfig } from './cpmBucketManager.js'; import { deepAccess, deepClone, @@ -16,11 +16,11 @@ import { logWarn, mergeDeep } from './utils.js'; -import {DEBUG_MODE} from './constants.js'; -import type {UserSyncConfig} from "./userSync.ts"; -import type {DeepPartial, DeepProperty, DeepPropertyName, TypeOfDeepProperty} from "./types/objects.d.ts"; -import type {BidderCode} from "./types/common.d.ts"; -import type {ORTBRequest} from "./types/ortb/request.d.ts"; +import { DEBUG_MODE } from './constants.js'; +import type { UserSyncConfig } from "./userSync.ts"; +import type { DeepPartial, DeepProperty, DeepPropertyName, TypeOfDeepProperty } from "./types/objects.d.ts"; +import type { BidderCode } from "./types/common.d.ts"; +import type { ORTBRequest } from "./types/ortb/request.d.ts"; const DEFAULT_DEBUG = getParameterByName(DEBUG_MODE).toUpperCase() === 'TRUE'; const DEFAULT_BIDDER_TIMEOUT = 3000; @@ -102,7 +102,7 @@ function attachProperties(config, useDefaultValues = true) { function setProp(name, val) { if (!values.hasOwnProperty(name)) { - Object.defineProperty(config, name, {enumerable: true}); + Object.defineProperty(config, name, { enumerable: true }); } values[name] = val; } @@ -254,6 +254,11 @@ export interface Config { * https://docs.prebid.org/features/firstPartyData.html */ ortb2?: DeepPartial; + /** + * List of fingerprinting APIs to disable. When an API is listed, the corresponding library + * returns a safe default instead of reading the real value. Supported: 'devicepixelratio', 'webdriver', 'resolvedoptions'. + */ + disableFingerprintingApis?: Array<'devicepixelratio' | 'webdriver' | 'resolvedoptions'>; } type PartialConfig = Partial & { [setting: string]: unknown }; @@ -262,7 +267,7 @@ type BidderConfig = { config: PartialConfig; } -type TopicalConfig = {[K in DeepPropertyName]: S extends DeepProperty ? TypeOfDeepProperty : unknown}; +type TopicalConfig = { [K in DeepPropertyName]: S extends DeepProperty ? TypeOfDeepProperty : unknown }; type UnregistrationFn = () => void; type GetConfigOptions = { @@ -499,7 +504,7 @@ export function newConfig() { if (topic === ALL_TOPICS) { callback(getConfig()); } else { - callback({[topic]: getConfig(topic)}); + callback({ [topic]: getConfig(topic) }); } } diff --git a/src/consentHandler.ts b/src/consentHandler.ts index b3fa9594673..1c1ae7a0355 100644 --- a/src/consentHandler.ts +++ b/src/consentHandler.ts @@ -1,7 +1,7 @@ -import {cyrb53Hash, isStr, timestamp} from './utils.js'; -import {defer, PbPromise} from './utils/promise.js'; -import {config} from './config.js'; -import type {ModuleType} from "./activities/modules.ts"; +import { cyrb53Hash, isStr, timestamp } from './utils.js'; +import { defer, PbPromise } from './utils/promise.js'; +import { config } from './config.js'; +import type { ModuleType } from "./activities/modules.ts"; /** * Placeholder gvlid for when vendor consent is not required. When this value is used as gvlid, the gdpr @@ -212,7 +212,7 @@ export function gvlidRegistry() { * `gvlid` is the single GVL ID for this family of modules (only defined if all modules with this name declare the same ID). */ get(moduleName: string) { - const result: GVLIDResult = {modules: registry[moduleName] || {}}; + const result: GVLIDResult = { modules: registry[moduleName] || {} }; if (flat.hasOwnProperty(moduleName) && flat[moduleName] !== none) { result.gvlid = flat[moduleName]; } @@ -266,7 +266,7 @@ export type AllConsentData = { } interface MultiHandler extends Pick, 'promise' | 'hash' | 'getConsentData' | 'reset'> { - getConsentMeta(): {[K in keyof typeof ALL_HANDLERS]: ReturnType<(typeof ALL_HANDLERS)[K]['getConsentMeta']>} + getConsentMeta(): { [K in keyof typeof ALL_HANDLERS]: ReturnType<(typeof ALL_HANDLERS)[K]['getConsentMeta']> } } export function multiHandler(handlers = ALL_HANDLERS): MultiHandler { diff --git a/src/creativeRenderers.js b/src/creativeRenderers.js index dcbfd2b40ba..5b65d4e6cb1 100644 --- a/src/creativeRenderers.js +++ b/src/creativeRenderers.js @@ -1,8 +1,8 @@ -import {PbPromise} from './utils/promise.js'; -import {createInvisibleIframe} from './utils.js'; +import { PbPromise } from './utils/promise.js'; +import { createInvisibleIframe } from './utils.js'; // eslint-disable-next-line prebid/validate-imports -import {RENDERER} from '../creative-renderers/display.js'; // autogenerated during precompilation -import {hook} from './hook.js'; +import { RENDERER } from '../creative-renderers/display.js'; // autogenerated during precompilation +import { hook } from './hook.js'; // the minimum rendererVersion that will be used by PUC export const PUC_MIN_VERSION = 3; diff --git a/src/debugging.js b/src/debugging.js index bd0baf3eddb..0bdcdf90e31 100644 --- a/src/debugging.js +++ b/src/debugging.js @@ -1,16 +1,16 @@ -import {config} from './config.js'; -import {getHook, hook} from './hook.js'; -import {getGlobal} from './prebidGlobal.js'; -import {logMessage, prefixLog} from './utils.js'; -import {createBid} from './bidfactory.js'; -import {loadExternalScript} from './adloader.js'; -import {PbPromise} from './utils/promise.js'; +import { config } from './config.js'; +import { getHook, hook } from './hook.js'; +import { getGlobal } from './prebidGlobal.js'; +import { logMessage, prefixLog } from './utils.js'; +import { createBid } from './bidfactory.js'; +import { loadExternalScript } from './adloader.js'; +import { PbPromise } from './utils/promise.js'; import { MODULE_TYPE_PREBID } from './activities/modules.js'; import * as utils from './utils.js'; -import {BANNER, NATIVE, VIDEO} from './mediaTypes.js'; -import {Renderer} from './Renderer.js'; +import { BANNER, NATIVE, VIDEO } from './mediaTypes.js'; +import { Renderer } from './Renderer.js'; -import {getDistUrlBase, getGlobalVarName} from './buildOptions.js'; +import { getDistUrlBase, getGlobalVarName } from './buildOptions.js'; export const DEBUG_KEY = `__${getGlobalVarName()}_debugging__`; @@ -24,7 +24,7 @@ function loadScript(url) { }); } -export function debuggingModuleLoader({alreadyInstalled = isDebuggingInstalled, script = loadScript} = {}) { +export function debuggingModuleLoader({ alreadyInstalled = isDebuggingInstalled, script = loadScript } = {}) { let loading = null; return function () { if (loading == null) { @@ -59,7 +59,7 @@ export function debuggingModuleLoader({alreadyInstalled = isDebuggingInstalled, } } -export function debuggingControls({load = debuggingModuleLoader(), hook = getHook('requestBids')} = {}) { +export function debuggingControls({ load = debuggingModuleLoader(), hook = getHook('requestBids') } = {}) { let promise = null; let enabled = false; function waitForDebugging(next, ...args) { @@ -74,14 +74,14 @@ export function debuggingControls({load = debuggingModuleLoader(), hook = getHoo } } function disable() { - hook.getHooks({hook: waitForDebugging}).remove(); + hook.getHooks({ hook: waitForDebugging }).remove(); enabled = false; } function reset() { promise = null; disable(); } - return {enable, disable, reset}; + return { enable, disable, reset }; } const ctl = debuggingControls(); @@ -107,6 +107,6 @@ export function loadSession() { } } -config.getConfig('debugging', function ({debugging}) { +config.getConfig('debugging', function ({ debugging }) { debugging?.enabled ? ctl.enable() : ctl.disable(); }); diff --git a/src/eventTrackers.js b/src/eventTrackers.js index b0c06cf0f1b..561084a1a4a 100644 --- a/src/eventTrackers.js +++ b/src/eventTrackers.js @@ -13,7 +13,7 @@ export const EVENT_TYPE_WIN = 500; * @returns {{[type: string]: {[method: string]: string[]}}} */ export function parseEventTrackers(eventTrackers) { - return (eventTrackers ?? []).reduce((tally, {event, method, url}) => { + return (eventTrackers ?? []).reduce((tally, { event, method, url }) => { const trackersForType = tally[event] = tally[event] ?? {}; const trackersForMethod = trackersForType[method] = trackersForType[method] ?? []; trackersForMethod.push(url); diff --git a/src/events.ts b/src/events.ts index 6ea102ab105..2e9603f3e7b 100644 --- a/src/events.ts +++ b/src/events.ts @@ -3,10 +3,10 @@ */ import * as utils from './utils.js' import { EVENTS, EVENT_ID_PATHS } from './constants.js'; -import {ttlCollection} from './utils/ttlCollection.js'; -import {config} from './config.js'; +import { ttlCollection } from './utils/ttlCollection.js'; +import { config } from './config.js'; -type CoreEvent = {[K in keyof typeof EVENTS]: typeof EVENTS[K]}[keyof typeof EVENTS]; +type CoreEvent = { [K in keyof typeof EVENTS]: typeof EVENTS[K] }[keyof typeof EVENTS]; // hide video events (unless the video module is included) with this one weird trick @@ -191,7 +191,7 @@ const _public = (function () { utils._setEventEmitter(_public.emit.bind(_public)); -export const {on, off, get, getEvents, emit, addEvents, has} = _public; +export const { on, off, get, getEvents, emit, addEvents, has } = _public; export function clearEvents() { eventsFired.clear(); diff --git a/src/fpd/enrichment.ts b/src/fpd/enrichment.ts index 1ccaaaf6692..107d98d9667 100644 --- a/src/fpd/enrichment.ts +++ b/src/fpd/enrichment.ts @@ -1,6 +1,6 @@ -import {hook} from '../hook.js'; -import {getRefererInfo, parseDomain} from '../refererDetection.js'; -import {findRootDomain} from './rootDomain.js'; +import { hook } from '../hook.js'; +import { getRefererInfo, parseDomain } from '../refererDetection.js'; +import { findRootDomain } from './rootDomain.js'; import { deepSetValue, deepAccess, @@ -13,14 +13,14 @@ import { memoize } from '../utils.js'; import { getDNT } from '../../libraries/dnt/index.js'; -import {config} from '../config.js'; -import {getHighEntropySUA, getLowEntropySUA} from './sua.js'; -import {PbPromise} from '../utils/promise.js'; -import {CLIENT_SECTIONS, clientSectionChecker, hasSection} from './oneClient.js'; -import {isActivityAllowed} from '../activities/rules.js'; -import {activityParams} from '../activities/activityParams.js'; -import {ACTIVITY_ACCESS_DEVICE} from '../activities/activities.js'; -import {MODULE_TYPE_PREBID} from '../activities/modules.js'; +import { config } from '../config.js'; +import { getHighEntropySUA, getLowEntropySUA } from './sua.js'; +import { PbPromise } from '../utils/promise.js'; +import { CLIENT_SECTIONS, clientSectionChecker, hasSection } from './oneClient.js'; +import { isActivityAllowed } from '../activities/rules.js'; +import { activityParams } from '../activities/activityParams.js'; +import { ACTIVITY_ACCESS_DEVICE } from '../activities/activities.js'; +import { MODULE_TYPE_PREBID } from '../activities/modules.js'; import { getViewportSize } from '../../libraries/viewport/viewport.js'; export const dep = { @@ -153,7 +153,7 @@ const ENRICHMENTS = { const h = getWinDimensions().screen.height; // vpw and vph are the viewport dimensions of the browser window - const {width: vpw, height: vph} = getViewportSize(); + const { width: vpw, height: vph } = getViewportSize(); const device = { w, @@ -220,7 +220,7 @@ export const getMetaTagKeywords = memoize(() => { // Enrichment of properties common across dooh, app and site - will be dropped into whatever // section is appropriate function clientEnrichment(ortb2, ri) { - const domain = parseDomain(ri.page, {noLeadingWww: true}); + const domain = parseDomain(ri.page, { noLeadingWww: true }); const keywords = new Set(); if (config.getConfig('firstPartyData.keywords.meta') ?? true) { (getMetaTagKeywords() ?? []).forEach(key => keywords.add(key)); diff --git a/src/fpd/normalize.js b/src/fpd/normalize.js index d28bdde3802..66a9dbb54f4 100644 --- a/src/fpd/normalize.js +++ b/src/fpd/normalize.js @@ -1,5 +1,5 @@ -import {deepEqual, deepSetValue, deepAccess, logWarn} from '../utils.js'; -import {hook} from '../hook.js'; +import { deepEqual, deepSetValue, deepAccess, logWarn } from '../utils.js'; +import { hook } from '../hook.js'; export const normalizeFPD = hook('sync', function(ortb2Fragments) { [ diff --git a/src/fpd/oneClient.js b/src/fpd/oneClient.js index 67f53c73bd8..4262367d1d5 100644 --- a/src/fpd/oneClient.js +++ b/src/fpd/oneClient.js @@ -1,4 +1,4 @@ -import {logWarn} from '../utils.js'; +import { logWarn } from '../utils.js'; // mutually exclusive ORTB sections in order of priority - 'dooh' beats 'app' & 'site' and 'app' beats 'site'; // if one is set, the others will be removed diff --git a/src/fpd/rootDomain.js b/src/fpd/rootDomain.js index 60497c8ff81..24256426610 100644 --- a/src/fpd/rootDomain.js +++ b/src/fpd/rootDomain.js @@ -1,5 +1,5 @@ -import {memoize} from '../utils.js'; -import {canSetCookie, getCoreStorageManager} from '../storageManager.js'; +import { memoize } from '../utils.js'; +import { canSetCookie, getCoreStorageManager } from '../storageManager.js'; export const coreStorage = getCoreStorageManager('fpdEnrichment'); diff --git a/src/fpd/sua.js b/src/fpd/sua.js index ac34951e347..aef2d840976 100644 --- a/src/fpd/sua.js +++ b/src/fpd/sua.js @@ -1,5 +1,5 @@ -import {isEmptyStr, isStr, isEmpty} from '../utils.js'; -import {PbPromise} from '../utils/promise.js'; +import { isEmptyStr, isStr, isEmpty } from '../utils.js'; +import { PbPromise } from '../utils/promise.js'; export const SUA_SOURCE_UNKNOWN = 0; export const SUA_SOURCE_LOW_ENTROPY = 1; @@ -77,19 +77,19 @@ export function highEntropySUAAccessor(uaData = window.navigator?.userAgentData) */ export function uaDataToSUA(source, uaData) { function toBrandVersion(brand, version) { - const bv = {brand}; + const bv = { brand }; if (isStr(version) && !isEmptyStr(version)) { bv.version = version.split('.'); } return bv; } - const sua = {source}; + const sua = { source }; if (uaData.platform) { sua.platform = toBrandVersion(uaData.platform, uaData.platformVersion); } if (uaData.fullVersionList || uaData.brands) { - sua.browsers = (uaData.fullVersionList || uaData.brands).map(({brand, version}) => toBrandVersion(brand, version)); + sua.browsers = (uaData.fullVersionList || uaData.brands).map(({ brand, version }) => toBrandVersion(brand, version)); } if (typeof uaData['mobile'] !== 'undefined') { sua.mobile = uaData.mobile ? 1 : 0; diff --git a/src/hook.ts b/src/hook.ts index 9aabc5b4ea3..1d78bb23dcc 100644 --- a/src/hook.ts +++ b/src/hook.ts @@ -1,7 +1,7 @@ import funHooks from 'fun-hooks/no-eval/index.js'; -import {defer} from './utils/promise.js'; -import type {AnyFunction, Wraps} from "./types/functions.d.ts"; -import type {AllExceptLast, Last} from "./types/tuples.d.ts"; +import { defer } from './utils/promise.js'; +import type { AnyFunction, Wraps } from "./types/functions.d.ts"; +import type { AllExceptLast, Last } from "./types/tuples.d.ts"; export type Next = { (...args: Parameters): unknown; @@ -66,14 +66,14 @@ export const ready: Promise = readyCtl.promise; export const getHook = hook.get; export function setupBeforeHookFnOnce(baseFn: Hookable, hookFn: BeforeHook, priority = 15) { - const result = baseFn.getHooks({hook: hookFn}); + const result = baseFn.getHooks({ hook: hookFn }); if (result.length === 0) { baseFn.before(hookFn, priority); } } const submoduleInstallMap = {}; -export function module(name, install, {postInstallAllowed = false} = {}) { +export function module(name, install, { postInstallAllowed = false } = {}) { hook('async', function (submodules) { submodules.forEach(args => install(...args)); if (postInstallAllowed) submoduleInstallMap[name] = install; @@ -99,7 +99,7 @@ export function submodule(name: N, ...args: Submodul export function wrapHook(hook: Hookable, wrapper: FN): Hookable { Object.defineProperties( wrapper, - Object.fromEntries(['before', 'after', 'getHooks', 'removeAll'].map((m) => [m, {get: () => hook[m]}])) + Object.fromEntries(['before', 'after', 'getHooks', 'removeAll'].map((m) => [m, { get: () => hook[m] }])) ); return (wrapper as unknown) as Hookable; } diff --git a/src/mediaTypes.ts b/src/mediaTypes.ts index ed7c4244878..01012985639 100644 --- a/src/mediaTypes.ts +++ b/src/mediaTypes.ts @@ -4,11 +4,11 @@ * All adapters are assumed to support banner ads. Other media types are specified by Adapters when they * register themselves with prebid-core. */ -import type {BannerMediaType} from "./banner.ts"; -import type {RendererConfig} from "./adUnits.ts"; -import type {VideoMediaType} from "./video.ts"; -import type {NativeMediaType} from "./native.ts"; -import {AudioMediaType} from "./audio.ts"; +import type { BannerMediaType } from "./banner.ts"; +import type { RendererConfig } from "./adUnits.ts"; +import type { VideoMediaType } from "./video.ts"; +import type { NativeMediaType } from "./native.ts"; +import { AudioMediaType } from "./audio.ts"; export type MediaType = typeof NATIVE | typeof VIDEO | typeof BANNER | typeof AUDIO; diff --git a/src/native.ts b/src/native.ts index 89a2bb8053d..f9e05d9ed34 100644 --- a/src/native.ts +++ b/src/native.ts @@ -12,7 +12,7 @@ import { triggerPixel } from './utils.js'; -import {auctionManager} from './auctionManager.js'; +import { auctionManager } from './auctionManager.js'; import { NATIVE_ASSET_TYPES, NATIVE_IMAGE_TYPES, @@ -20,17 +20,17 @@ import { NATIVE_KEYS_THAT_ARE_NOT_ASSETS, PREBID_NATIVE_DATA_KEYS_TO_ORTB } from './constants.js'; -import {NATIVE} from './mediaTypes.js'; -import {getRenderingData} from './adRendering.js'; -import {getCreativeRendererSource, PUC_MIN_VERSION} from './creativeRenderers.js'; -import {EVENT_TYPE_IMPRESSION, parseEventTrackers, TRACKER_METHOD_IMG, TRACKER_METHOD_JS} from './eventTrackers.js'; -import type {Link, NativeRequest, NativeResponse} from "./types/ortb/native.d.ts"; -import type {Size} from "./types/common.d.ts"; -import type {Ext} from "./types/ortb/common.d.ts"; -import type {BidResponse, NativeBidResponse} from "./bidfactory.ts"; -import type {AdUnit} from "./adUnits.ts"; - -type LegacyAssets = Omit<{[K in keyof (typeof NATIVE_KEYS)]: unknown}, (typeof NATIVE_KEYS_THAT_ARE_NOT_ASSETS)[number]>; +import { NATIVE } from './mediaTypes.js'; +import { getRenderingData } from './adRendering.js'; +import { getCreativeRendererSource, PUC_MIN_VERSION } from './creativeRenderers.js'; +import { EVENT_TYPE_IMPRESSION, parseEventTrackers, TRACKER_METHOD_IMG, TRACKER_METHOD_JS } from './eventTrackers.js'; +import type { Link, NativeRequest, NativeResponse } from "./types/ortb/native.d.ts"; +import type { Size } from "./types/common.d.ts"; +import type { Ext } from "./types/ortb/common.d.ts"; +import type { BidResponse, NativeBidResponse } from "./bidfactory.ts"; +import type { AdUnit } from "./adUnits.ts"; + +type LegacyAssets = Omit<{ [K in keyof (typeof NATIVE_KEYS)]: unknown }, (typeof NATIVE_KEYS_THAT_ARE_NOT_ASSETS)[number]>; type LegacyImageAssets = { icon: unknown, image: unknown }; type LegacyImageAssetResponse = { @@ -293,7 +293,7 @@ export const hasNonNativeBidder = adUnit => * bid Native bid to validate * @return {Boolean} If object is valid */ -export function nativeBidIsValid(bid, {index = auctionManager.index} = {}) { +export function nativeBidIsValid(bid, { index = auctionManager.index } = {}) { const adUnit = index.getAdUnit(bid); if (!adUnit) { return false; } const ortbRequest = adUnit.nativeOrtbRequest @@ -355,8 +355,8 @@ export function fireNativeTrackers(message, bidResponse) { return message.action; } -export function fireImpressionTrackers(nativeResponse, {runMarkup = (mkup) => insertHtmlIntoIframe(mkup), fetchURL = triggerPixel} = {}) { - let {[TRACKER_METHOD_IMG]: img = [], [TRACKER_METHOD_JS]: js = []} = parseEventTrackers( +export function fireImpressionTrackers(nativeResponse, { runMarkup = (mkup) => insertHtmlIntoIframe(mkup), fetchURL = triggerPixel } = {}) { + let { [TRACKER_METHOD_IMG]: img = [], [TRACKER_METHOD_JS]: js = [] } = parseEventTrackers( nativeResponse.eventtrackers || [] )[EVENT_TYPE_IMPRESSION] || {}; @@ -375,7 +375,7 @@ export function fireImpressionTrackers(nativeResponse, {runMarkup = (mkup) => in } } -export function fireClickTrackers(nativeResponse, assetId = null, {fetchURL = triggerPixel} = {}) { +export function fireClickTrackers(nativeResponse, assetId = null, { fetchURL = triggerPixel } = {}) { // legacy click tracker if (!assetId) { (nativeResponse.link?.clicktrackers || []).forEach(url => fetchURL(url)); @@ -423,7 +423,7 @@ function getNativeAssets(nativeProps, keys, ext = false) { if (ext === false && key === 'ext') { assets.push(...getNativeAssets(value, keys, true)); } else if (ext || NATIVE_KEYS.hasOwnProperty(key)) { - assets.push({key, value: getAssetValue(value)}); + assets.push({ key, value: getAssetValue(value) }); } }); return assets; @@ -443,7 +443,7 @@ export function getNativeRenderingData(bid, adUnit, keys) { return data; } -function assetsMessage(data, adObject, keys, {index = auctionManager.index} = {}) { +function assetsMessage(data, adObject, keys, { index = auctionManager.index } = {}) { const msg: any = { message: 'assetResponse', adId: data.adId, @@ -457,7 +457,7 @@ function assetsMessage(data, adObject, keys, {index = auctionManager.index} = {} msg.renderer = getCreativeRendererSource(adObject); msg.rendererVersion = PUC_MIN_VERSION; if (keys != null) { - renderData.assets = renderData.assets.filter(({key}) => keys.includes(key)) + renderData.assets = renderData.assets.filter(({ key }) => keys.includes(key)) } } else { renderData = getNativeRenderingData(adObject, index.getAdUnit(adObject), keys); diff --git a/src/pbjsORTB.ts b/src/pbjsORTB.ts index 9653fa82558..20656c7d85e 100644 --- a/src/pbjsORTB.ts +++ b/src/pbjsORTB.ts @@ -9,7 +9,7 @@ export function processorRegistry() { const processors = {}; return { - registerOrtbProcessor({type, name, fn, priority = 0, dialects = [DEFAULT]}) { + registerOrtbProcessor({ type, name, fn, priority = 0, dialects = [DEFAULT] }) { if (!types.has(type)) { throw new Error(`ORTB processor type must be one of: ${PROCESSOR_TYPES.join(', ')}`) } @@ -32,4 +32,4 @@ export function processorRegistry() { } } -export const {registerOrtbProcessor, getProcessors} = processorRegistry(); +export const { registerOrtbProcessor, getProcessors } = processorRegistry(); diff --git a/src/prebid.public.ts b/src/prebid.public.ts index 3404b32ef4d..5f30a10900b 100644 --- a/src/prebid.public.ts +++ b/src/prebid.public.ts @@ -3,5 +3,5 @@ // to get around this problem. import './types/summary/core.d.ts'; import './types/summary/global.d.ts'; -export {default} from './prebid.ts'; +export { default } from './prebid.ts'; export type * from './types/summary/exports.d.ts'; diff --git a/src/prebid.ts b/src/prebid.ts index 34d6208970a..5d37a6dcce8 100644 --- a/src/prebid.ts +++ b/src/prebid.ts @@ -1,6 +1,6 @@ /** @module pbjs */ -import {getGlobal, type PrebidJS} from './prebidGlobal.js'; +import { getGlobal, type PrebidJS } from './prebidGlobal.js'; import { deepAccess, deepClone, @@ -24,22 +24,22 @@ import { uniques, unsupportedBidderMessage } from './utils.js'; -import {listenMessagesFromCreative} from './secureCreatives.js'; -import {userSync} from './userSync.js'; -import {config} from './config.js'; -import {auctionManager} from './auctionManager.js'; -import {isBidUsable, type SlotMatchingFn, targeting} from './targeting.js'; -import {hook, wrapHook} from './hook.js'; -import {loadSession} from './debugging.js'; -import {storageCallbacks} from './storageManager.js'; -import adapterManager, {type AliasBidderOptions, type BidRequest, getS2SBidderSet} from './adapterManager.js'; -import {BID_STATUS, EVENTS, NATIVE_KEYS} from './constants.js'; -import type {Event, EventHandler, EventIDs} from "./events.js"; +import { listenMessagesFromCreative } from './secureCreatives.js'; +import { userSync } from './userSync.js'; +import { config } from './config.js'; +import { auctionManager } from './auctionManager.js'; +import { isBidUsable, type SlotMatchingFn, targeting } from './targeting.js'; +import { hook, wrapHook } from './hook.js'; +import { loadSession } from './debugging.js'; +import { storageCallbacks } from './storageManager.js'; +import adapterManager, { type AliasBidderOptions, type BidRequest, getS2SBidderSet } from './adapterManager.js'; +import { BID_STATUS, EVENTS, NATIVE_KEYS } from './constants.js'; +import type { Event, EventHandler, EventIDs } from "./events.js"; import * as events from './events.js'; -import {type Metrics, newMetrics, useMetrics} from './utils/perfMetrics.js'; -import {type Defer, defer, PbPromise} from './utils/promise.js'; -import {enrichFPD} from './fpd/enrichment.js'; -import {allConsent} from './consentHandler.js'; +import { type Metrics, newMetrics, useMetrics } from './utils/perfMetrics.js'; +import { type Defer, defer, PbPromise } from './utils/promise.js'; +import { enrichFPD } from './fpd/enrichment.js'; +import { allConsent } from './consentHandler.js'; import { insertLocatorFrame, markBidAsRendered, @@ -47,24 +47,24 @@ import { renderAdDirect, renderIfDeferred } from './adRendering.js'; -import {getHighestCpm} from './utils/reducers.js'; -import {fillVideoDefaults, ORTB_VIDEO_PARAMS} from './video.js'; -import {ORTB_BANNER_PARAMS} from './banner.js'; -import {BANNER, VIDEO} from './mediaTypes.js'; -import {delayIfPrerendering} from './utils/prerendering.js'; -import {type BidAdapter, type BidderSpec, newBidder} from './adapters/bidderFactory.js'; -import {normalizeFPD} from './fpd/normalize.js'; -import type {Bid} from "./bidfactory.ts"; -import type {AdUnit, AdUnitDefinition, BidderParams} from "./adUnits.ts"; -import type {AdUnitCode, BidderCode, ByAdUnit, Identifier, ORTBFragments} from "./types/common.d.ts"; -import type {ORTBRequest} from "./types/ortb/request.d.ts"; -import type {DeepPartial} from "./types/objects.d.ts"; -import type {AnyFunction, Wraps} from "./types/functions.d.ts"; -import type {BidderScopedSettings, BidderSettings} from "./bidderSettings.ts"; -import {fillAudioDefaults, ORTB_AUDIO_PARAMS} from './audio.ts'; - -import {getGlobalVarName} from "./buildOptions.ts"; -import {yieldAll} from "./utils/yield.ts"; +import { getHighestCpm } from './utils/reducers.js'; +import { fillVideoDefaults, ORTB_VIDEO_PARAMS } from './video.js'; +import { ORTB_BANNER_PARAMS } from './banner.js'; +import { BANNER, VIDEO } from './mediaTypes.js'; +import { delayIfPrerendering } from './utils/prerendering.js'; +import { type BidAdapter, type BidderSpec, newBidder } from './adapters/bidderFactory.js'; +import { normalizeFPD } from './fpd/normalize.js'; +import type { Bid } from "./bidfactory.ts"; +import type { AdUnit, AdUnitDefinition, BidderParams } from "./adUnits.ts"; +import type { AdUnitCode, BidderCode, ByAdUnit, Identifier, ORTBFragments } from "./types/common.d.ts"; +import type { ORTBRequest } from "./types/ortb/request.d.ts"; +import type { DeepPartial } from "./types/objects.d.ts"; +import type { AnyFunction, Wraps } from "./types/functions.d.ts"; +import type { BidderScopedSettings, BidderSettings } from "./bidderSettings.ts"; +import { fillAudioDefaults, ORTB_AUDIO_PARAMS } from './audio.ts'; + +import { getGlobalVarName } from "./buildOptions.ts"; +import { yieldAll } from "./utils/yield.ts"; const pbjsInstance = getGlobal(); const { triggerUserSyncs } = userSync; @@ -172,14 +172,14 @@ function validateBannerMediaType(adUnit: AdUnit) { banner.format = format; try { formatSizes = format - .filter(({w, h, wratio, hratio}) => { + .filter(({ w, h, wratio, hratio }) => { if ((w ?? h) != null && (wratio ?? hratio) != null) { logWarn(`Ad unit banner.format specifies both w/h and wratio/hratio`, adUnit); return false; } return (w != null && h != null) || (wratio != null && hratio != null); }) - .map(({w, h, wratio, hratio}) => [w ?? wratio, h ?? hratio]); + .map(({ w, h, wratio, hratio }) => [w ?? wratio, h ?? hratio]); } catch (e) { logError(`Invalid format definition on ad unit ${adUnit.code}`, format); } @@ -352,7 +352,7 @@ function validateAdUnit(adUnitDef: AdUnitDefinition): AdUnit { return null; } if (adUnit.ortb2Imp != null && (bids == null || bids.length === 0)) { - adUnit.bids = [{bidder: null}]; // the 'null' bidder is treated as an s2s-only placeholder by adapterManager + adUnit.bids = [{ bidder: null }]; // the 'null' bidder is treated as an s2s-only placeholder by adapterManager logMessage(msg(`defines 'adUnit.ortb2Imp' with no 'adUnit.bids'; it will be seen only by S2S adapters`)); } @@ -786,17 +786,17 @@ export const requestBids = (function() { adUnitCodes = adUnitCodes.filter(uniques); return Object.assign({ adUnitCodes - }, adUnits.reduce(({included, excluded}, adUnit) => { + }, adUnits.reduce(({ included, excluded }, adUnit) => { (adUnitCodes.includes(adUnit.code) ? included : excluded).push(adUnit); - return {included, excluded}; - }, {included: [], excluded: []})) + return { included, excluded }; + }, { included: [], excluded: [] })) } } const delegate = hook('async', function (reqBidOptions: PrivRequestBidsOptions): void { let { bidsBackHandler, timeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2, metrics, defer } = reqBidOptions ?? {}; const cbTimeout = timeout || config.getConfig('bidderTimeout'); - ({included: adUnits, adUnitCodes} = filterAdUnits(adUnits, adUnitCodes)); + ({ included: adUnits, adUnitCodes } = filterAdUnits(adUnits, adUnitCodes)); let ortb2Fragments = { global: mergeDeep({}, config.getAnyConfig('ortb2') || {}, ortb2 || {}), bidder: Object.fromEntries(Object.entries(config.getBidderConfig()).map(([bidder, cfg]) => [bidder, deepClone(cfg.ortb2)]).filter(([_, ortb2]) => ortb2 != null)) @@ -805,7 +805,7 @@ export const requestBids = (function() { enrichFPD(PbPromise.resolve(ortb2Fragments.global)).then(global => { ortb2Fragments.global = global; - return startAuction({bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics, defer}); + return startAuction({ bidsBackHandler, timeout: cbTimeout, adUnits, adUnitCodes, labels, auctionId, ttlBuffer, ortb2Fragments, metrics, defer }); }) }, 'requestBids'); @@ -822,7 +822,7 @@ export const requestBids = (function() { const metrics = newMetrics(); metrics.checkpoint('requestBids'); - const {included, excluded, adUnitCodes} = filterAdUnits(adUnits, options.adUnitCodes); + const { included, excluded, adUnitCodes } = filterAdUnits(adUnits, options.adUnitCodes); events.emit(REQUEST_BIDS, Object.assign(options, { adUnits: included, @@ -838,7 +838,7 @@ export const requestBids = (function() { // what it means for an event handler to modify adUnitCodes - so don't allow it adUnitCodes, metrics, - defer: defer({promiseFactory: (r) => new Promise(r)}) + defer: defer({ promiseFactory: (r) => new Promise(r) }) }); delegate.call(this, req); return req.defer.promise; @@ -1161,7 +1161,7 @@ type MarkWinningBidAsUsedOptions = ({ /** * Mark the winning bid as used, should only be used in conjunction with video */ -function markWinningBidAsUsed({adId, adUnitCode, analytics = false, events = false}: MarkWinningBidAsUsedOptions) { +function markWinningBidAsUsed({ adId, adUnitCode, analytics = false, events = false }: MarkWinningBidAsUsedOptions) { let bids; if (adUnitCode && adId == null) { bids = targeting.getWinningBids(adUnitCode); @@ -1273,7 +1273,7 @@ addApiMethod('processQueue', processQueue, false); * Manually trigger billing for a winning bid, idendified either by ad ID or ad unit code. * Used in conjunction with `adUnit.deferBilling`. */ -function triggerBilling({adId, adUnitCode}: { +function triggerBilling({ adId, adUnitCode }: { adId?: string; adUnitCode?: AdUnitCode }) { diff --git a/src/prebidGlobal.ts b/src/prebidGlobal.ts index c64e408bcf6..7794f2a9f6c 100644 --- a/src/prebidGlobal.ts +++ b/src/prebidGlobal.ts @@ -1,4 +1,4 @@ -import {getGlobalVarName, shouldDefineGlobal} from "./buildOptions.ts"; +import { getGlobalVarName, shouldDefineGlobal } from "./buildOptions.ts"; interface Command { (): any; diff --git a/src/refererDetection.ts b/src/refererDetection.ts index 43e6d890aa0..fb8e1ccc880 100644 --- a/src/refererDetection.ts +++ b/src/refererDetection.ts @@ -9,7 +9,7 @@ */ import { config } from './config.js'; -import {logWarn} from './utils.js'; +import { logWarn } from './utils.js'; /** * Prepend a URL with the page's protocol (http/https), if necessary. @@ -40,7 +40,7 @@ export function ensureProtocol(url, win = window) { * @param options.noPort - If true, do not include the ':[port]' portion. * @return The extracted domain or undefined if the URL is invalid. */ -export function parseDomain(url: string, {noLeadingWww = false, noPort = false} = {}): string | null { +export function parseDomain(url: string, { noLeadingWww = false, noPort = false } = {}): string | null { let target; try { target = new URL(ensureProtocol(url)); diff --git a/src/secureCreatives.js b/src/secureCreatives.js index 8233c373d1a..cbcf8e85bdd 100644 --- a/src/secureCreatives.js +++ b/src/secureCreatives.js @@ -3,9 +3,9 @@ access to a publisher page from creative payloads. */ -import {getAllAssetsMessage, getAssetMessage} from './native.js'; -import {BID_STATUS, MESSAGES} from './constants.js'; -import {isApnGetTagDefined, isGptPubadsDefined, logError, logWarn} from './utils.js'; +import { getAllAssetsMessage, getAssetMessage } from './native.js'; +import { BID_STATUS, MESSAGES } from './constants.js'; +import { isApnGetTagDefined, isGptPubadsDefined, logError, logWarn } from './utils.js'; import { deferRendering, getBidToRender, @@ -14,8 +14,8 @@ import { handleRender, markWinner } from './adRendering.js'; -import {getCreativeRendererSource, PUC_MIN_VERSION} from './creativeRenderers.js'; -import {PbPromise} from './utils/promise.js'; +import { getCreativeRendererSource, PUC_MIN_VERSION } from './creativeRenderers.js'; +import { PbPromise } from './utils/promise.js'; const { REQUEST, RESPONSE, NATIVE, EVENT } = MESSAGES; @@ -56,7 +56,7 @@ export function getReplier(ev) { function ensureAdId(adId, reply) { return function (data, ...args) { - return reply(Object.assign({}, data, {adId}), ...args); + return reply(Object.assign({}, data, { adId }), ...args); } } @@ -82,7 +82,7 @@ function getResizer(adId, bidResponse) { // the first is the one that was requested and is tied to the element // the second is the one that is being rendered (sometimes different, e.g. in some paapi setups) return function (width, height) { - resizeRemoteCreative({...bidResponse, width, height, adId}); + resizeRemoteCreative({ ...bidResponse, width, height, adId }); } } function handleRenderRequest(reply, message, bidResponse) { @@ -119,7 +119,7 @@ function handleNativeRequest(reply, data, adObject) { deferRendering(adObject, () => reply(getAllAssetsMessage(data, adObject))); break; default: - handleNativeMessage(data, adObject, {resizeFn: getResizer(data.adId, adObject)}); + handleNativeMessage(data, adObject, { resizeFn: getResizer(data.adId, adObject) }); markWinner(adObject); } } @@ -152,7 +152,7 @@ export function resizeAnchor(ins, width, height) { // wait until GPT has set dimensions on the ins, otherwise our changes will be overridden const resizer = setInterval(() => { let done = false; - Object.entries({width, height}) + Object.entries({ width, height }) .forEach(([dimension, newValue]) => { if (/\d+px/.test(ins.style[dimension])) { ins.style[dimension] = getDimension(newValue); @@ -167,7 +167,7 @@ export function resizeAnchor(ins, width, height) { }) } -export function resizeRemoteCreative({instl, adId, adUnitCode, width, height}) { +export function resizeRemoteCreative({ instl, adId, adUnitCode, width, height }) { // do not resize interstitials - the creative frame takes the full screen and sizing of the ad should // be handled within it. if (instl) return; diff --git a/src/storageManager.ts b/src/storageManager.ts index c5c2862965f..998a3cbdbca 100644 --- a/src/storageManager.ts +++ b/src/storageManager.ts @@ -1,7 +1,7 @@ -import {checkCookieSupport, hasDeviceAccess, logError, memoize, timestamp} from './utils.js'; -import {bidderSettings} from './bidderSettings.js'; -import {MODULE_TYPE_BIDDER, MODULE_TYPE_PREBID, type ModuleType} from './activities/modules.js'; -import {isActivityAllowed, registerActivityControl} from './activities/rules.js'; +import { checkCookieSupport, hasDeviceAccess, logError, memoize, timestamp } from './utils.js'; +import { bidderSettings } from './bidderSettings.js'; +import { MODULE_TYPE_BIDDER, MODULE_TYPE_PREBID, type ModuleType } from './activities/modules.js'; +import { isActivityAllowed, registerActivityControl } from './activities/rules.js'; import { ACTIVITY_PARAM_ADAPTER_CODE, ACTIVITY_PARAM_COMPONENT_TYPE, @@ -10,13 +10,13 @@ import { ACTIVITY_PARAM_STORAGE_WRITE } from './activities/params.js'; -import {ACTIVITY_ACCESS_DEVICE, ACTIVITY_ACCESS_REQUEST_CREDENTIALS} from './activities/activities.js'; -import {config} from './config.js'; -import {hook} from "./hook.ts"; +import { ACTIVITY_ACCESS_DEVICE, ACTIVITY_ACCESS_REQUEST_CREDENTIALS } from './activities/activities.js'; +import { config } from './config.js'; +import { hook } from "./hook.ts"; import adapterManager from './adapterManager.js'; -import {activityParams} from './activities/activityParams.js'; -import type {AnyFunction} from "./types/functions.d.ts"; -import type {BidderCode} from "./types/common.d.ts"; +import { activityParams } from './activities/activityParams.js'; +import type { AnyFunction } from "./types/functions.d.ts"; +import type { BidderCode } from "./types/common.d.ts"; export const STORAGE_TYPE_LOCALSTORAGE = 'html5'; export const STORAGE_TYPE_COOKIES = 'cookie'; @@ -57,14 +57,14 @@ export type StorageManager = { /* * Storage manager constructor. Consumers should prefer one of `getStorageManager` or `getCoreStorageManager`. */ -export function newStorageManager({moduleName, moduleType, advertiseKeys = true}: { +export function newStorageManager({ moduleName, moduleType, advertiseKeys = true }: { moduleName: string; moduleType: ModuleType; /** * If false, do not pass the 'storageKey' to activity checks - turning off storageControl for this manager. */ advertiseKeys?: boolean; -} = {} as any, {isAllowed = isActivityAllowed} = {}) { +} = {} as any, { isAllowed = isActivityAllowed } = {}) { function isValid(cb, storageType, storageKey, isWrite) { let mod = moduleName; const curBidder = config.getCurrentBidder(); @@ -262,7 +262,7 @@ export function newStorageManager({moduleName, moduleType, advertiseKeys = true} * for `{moduleType: 'bidder', moduleName: bidderCode}`. * */ -export function getStorageManager({moduleType, moduleName, bidderCode}: { +export function getStorageManager({ moduleType, moduleName, bidderCode }: { moduleType?: ModuleType; moduleName?: string; bidderCode?: BidderCode; @@ -277,7 +277,7 @@ export function getStorageManager({moduleType, moduleName, bidderCode}: { } else if (!moduleName || !moduleType) { err() } - return newStorageManager({moduleType, moduleName}); + return newStorageManager({ moduleType, moduleName }); } /** @@ -286,7 +286,7 @@ export function getStorageManager({moduleType, moduleName, bidderCode}: { * @param {string} moduleName Module name */ export function getCoreStorageManager(moduleName) { - return newStorageManager({moduleName: moduleName, moduleType: MODULE_TYPE_PREBID}); + return newStorageManager({ moduleName: moduleName, moduleType: MODULE_TYPE_PREBID }); } export const canSetCookie = (() => { @@ -326,7 +326,7 @@ export const canSetCookie = (() => { */ export function deviceAccessRule() { if (!hasDeviceAccess()) { - return {allow: false} + return { allow: false } } } registerActivityControl(ACTIVITY_ACCESS_DEVICE, 'deviceAccess config', deviceAccessRule); @@ -351,7 +351,7 @@ export function storageAllowedRule(params, bs = bidderSettings) { allow = Array.isArray(allow) ? allow.some((e) => e === storageType) : allow === storageType; } if (!allow) { - return {allow}; + return { allow }; } } diff --git a/src/targeting.ts b/src/targeting.ts index 477ddaab7f0..8b2f44b9a5b 100644 --- a/src/targeting.ts +++ b/src/targeting.ts @@ -1,11 +1,11 @@ -import {auctionManager} from './auctionManager.js'; -import {getBufferedTTL} from './bidTTL.js'; -import {bidderSettings} from './bidderSettings.js'; -import {config} from './config.js'; -import {BID_STATUS, DEFAULT_TARGETING_KEYS, EVENTS, JSON_MAPPING, TARGETING_KEYS} from './constants.js'; +import { auctionManager } from './auctionManager.js'; +import { getBufferedTTL } from './bidTTL.js'; +import { bidderSettings } from './bidderSettings.js'; +import { config } from './config.js'; +import { BID_STATUS, DEFAULT_TARGETING_KEYS, EVENTS, JSON_MAPPING, TARGETING_KEYS } from './constants.js'; import * as events from './events.js'; -import {hook} from './hook.js'; -import {ADPOD} from './mediaTypes.js'; +import { hook } from './hook.js'; +import { ADPOD } from './mediaTypes.js'; import { deepAccess, deepClone, @@ -22,11 +22,11 @@ import { timestamp, uniques, } from './utils.js'; -import {getHighestCpm, getOldestHighestCpmBid} from './utils/reducers.js'; -import type {Bid} from './bidfactory.ts'; -import type {AdUnitCode, ByAdUnit, Identifier} from './types/common.d.ts'; -import type {DefaultTargeting} from './auction.ts'; -import {lock} from "./targeting/lock.ts"; +import { getHighestCpm, getOldestHighestCpmBid } from './utils/reducers.js'; +import type { Bid } from './bidfactory.ts'; +import type { AdUnitCode, ByAdUnit, Identifier } from './types/common.d.ts'; +import type { DefaultTargeting } from './auction.ts'; +import { lock } from "./targeting/lock.ts"; var pbTargetingKeys = []; @@ -396,7 +396,7 @@ export function newTargeting(auctionManager) { // pt${n} keys should not be uppercased keywordsObj[key] = astTargeting[targetId][key]; } - window.apntag.setKeywords(targetId, keywordsObj, {overrideKeyValue: true}); + window.apntag.setKeywords(targetId, keywordsObj, { overrideKeyValue: true }); } }) } @@ -424,7 +424,7 @@ export function newTargeting(auctionManager) { (deals || allowedSendAllBidTargeting.indexOf(key) !== -1))); if (targetingValue) { - result.push({[bid.adUnitCode]: targetingValue}) + result.push({ [bid.adUnitCode]: targetingValue }) } } return result; @@ -538,7 +538,7 @@ export function newTargeting(auctionManager) { } }); - return {filteredBids, customKeysByUnit}; + return { filteredBids, customKeysByUnit }; } // warn about conflicting configuration @@ -733,11 +733,11 @@ export function newTargeting(auctionManager) { if (customKeysForUnit) { Object.keys(customKeysForUnit).forEach(key => { - if (key && customKeysForUnit[key]) targeting.push({[key]: customKeysForUnit[key]}); + if (key && customKeysForUnit[key]) targeting.push({ [key]: customKeysForUnit[key] }); }) } - acc.push({[newBid.adUnitCode]: targeting}); + acc.push({ [newBid.adUnitCode]: targeting }); return acc; }, []); @@ -747,7 +747,7 @@ export function newTargeting(auctionManager) { return keys.reduce((targeting, key) => { const value = bid.adserverTargeting[key]; if (value) { - targeting.push({[`${key}_${bid.bidderCode}`.substring(0, MAX_DFP_KEYLENGTH)]: [bid.adserverTargeting[key]]}) + targeting.push({ [`${key}_${bid.bidderCode}`.substring(0, MAX_DFP_KEYLENGTH)]: [bid.adserverTargeting[key]] }) } return targeting; }, []); @@ -756,7 +756,7 @@ export function newTargeting(auctionManager) { function getVersionTargeting(adUnitCodes) { let version = config.getConfig('targetingControls.version'); if (version === false) return []; - return adUnitCodes.map(au => ({[au]: [{[TARGETING_KEYS.VERSION]: [version ?? DEFAULT_HB_VER]}]})); + return adUnitCodes.map(au => ({ [au]: [{ [TARGETING_KEYS.VERSION]: [version ?? DEFAULT_HB_VER] }] })); } function getAdUnitTargeting(adUnitCodes) { @@ -770,7 +770,7 @@ export function newTargeting(auctionManager) { return Object.keys(aut) .map(function(key) { if (isStr(aut[key])) aut[key] = aut[key].split(',').map(s => s.trim()); - if (!isArray(aut[key])) aut[key] = [ aut[key] ]; + if (!isArray(aut[key])) aut[key] = [aut[key]]; return { [key]: aut[key] }; }); } @@ -780,7 +780,7 @@ export function newTargeting(auctionManager) { .reduce((result, adUnit) => { const targetingValues = getTargetingValues(adUnit); - if (targetingValues)result.push({[adUnit.code]: targetingValues}); + if (targetingValues)result.push({ [adUnit.code]: targetingValues }); return result; }, []); } diff --git a/src/targeting/lock.ts b/src/targeting/lock.ts index f59d7f1d890..f88a2b1c40c 100644 --- a/src/targeting/lock.ts +++ b/src/targeting/lock.ts @@ -1,7 +1,7 @@ -import type {TargetingMap} from "../targeting.ts"; -import {config} from "../config.ts"; -import {ttlCollection} from "../utils/ttlCollection.ts"; -import {isGptPubadsDefined} from "../utils.js"; +import type { TargetingMap } from "../targeting.ts"; +import { config } from "../config.ts"; +import { ttlCollection } from "../utils/ttlCollection.ts"; +import { isGptPubadsDefined } from "../utils.js"; import SlotRenderEndedEvent = googletag.events.SlotRenderEndedEvent; const DEFAULT_LOCK_TIMEOUT = 3000; @@ -34,7 +34,7 @@ export function targetingLock() { slack: 0, }); config.getConfig('targetingControls', (cfg) => { - ({lock: keys, lockTimeout: timeout = DEFAULT_LOCK_TIMEOUT} = cfg.targetingControls ?? {}); + ({ lock: keys, lockTimeout: timeout = DEFAULT_LOCK_TIMEOUT } = cfg.targetingControls ?? {}); if (keys != null && !Array.isArray(keys)) { keys = [keys]; } else if (keys == null) { @@ -44,7 +44,7 @@ export function targetingLock() { }) const [setupGpt, tearDownGpt] = (() => { let enabled = false; - function onGptRender({slot}: SlotRenderEndedEvent) { + function onGptRender({ slot }: SlotRenderEndedEvent) { keys?.forEach(key => slot.getTargeting(key)?.forEach(locked.delete)); } return [ diff --git a/src/types/common.d.ts b/src/types/common.d.ts index 3f385ab6868..a39b2c6d6c4 100644 --- a/src/types/common.d.ts +++ b/src/types/common.d.ts @@ -1,5 +1,5 @@ -import type {DeepPartial} from "./objects.d.ts"; -import type {ORTBRequest} from "./ortb/request.d.ts"; +import type { DeepPartial } from "./objects.d.ts"; +import type { ORTBRequest } from "./ortb/request.d.ts"; /** * Prebid-generated identifier. diff --git a/src/types/ortb/ext/dchain.d.ts b/src/types/ortb/ext/dchain.d.ts index 2db81a44c36..51ac0bf544f 100644 --- a/src/types/ortb/ext/dchain.d.ts +++ b/src/types/ortb/ext/dchain.d.ts @@ -1,6 +1,6 @@ // https://iabtechlab.com/wp-content/uploads/2021/03/DemandChainObject-1-0.pdf -import type {BooleanInt, Extensible} from "../common.d.ts"; +import type { BooleanInt, Extensible } from "../common.d.ts"; export type DemandChainNode = Extensible & { /** diff --git a/src/types/ortb/native.d.ts b/src/types/ortb/native.d.ts index ed099d10b11..c80ca986680 100644 --- a/src/types/ortb/native.d.ts +++ b/src/types/ortb/native.d.ts @@ -1,4 +1,4 @@ -import type {EventTrackerResponse as oEventTrackerResponse, NativeResponse as oNativeResponse, LinkResponse, NativeRequest as oNativeRequest} from 'iab-native'; +import type { EventTrackerResponse as oEventTrackerResponse, NativeResponse as oNativeResponse, LinkResponse, NativeRequest as oNativeRequest } from 'iab-native'; export type NativeRequest = oNativeRequest; export type EventTrackerResponse = oEventTrackerResponse; diff --git a/src/types/ortb/request.d.ts b/src/types/ortb/request.d.ts index 64cf842ccb1..87bbaa54ea1 100644 --- a/src/types/ortb/request.d.ts +++ b/src/types/ortb/request.d.ts @@ -1,9 +1,9 @@ /* eslint prebid/validate-imports: 0 */ -import type {Ext} from './common.d.ts'; -import type {DSARequest} from "./ext/dsa.d.ts"; +import type { Ext } from './common.d.ts'; +import type { DSARequest } from "./ext/dsa.d.ts"; -import type {BidRequest, Imp} from 'iab-openrtb/v26'; +import type { BidRequest, Imp } from 'iab-openrtb/v26'; type TidSource = 'pbjs' | 'pbjsStable' | 'pub'; diff --git a/src/types/ortb/response.d.ts b/src/types/ortb/response.d.ts index b5d7ffeecc3..f89cf7cdd99 100644 --- a/src/types/ortb/response.d.ts +++ b/src/types/ortb/response.d.ts @@ -1,7 +1,7 @@ -import type {BidResponse, SeatBid, Bid} from "iab-openrtb/v26"; -import type {Ext} from './common.d.ts'; -import type {DSAResponse} from "./ext/dsa.d.ts"; -import type {DemandChain} from "./ext/dchain.d.ts"; +import type { BidResponse, SeatBid, Bid } from "iab-openrtb/v26"; +import type { Ext } from './common.d.ts'; +import type { DSAResponse } from "./ext/dsa.d.ts"; +import type { DemandChain } from "./ext/dchain.d.ts"; export interface ORTBBid extends Bid { ext: Ext & { diff --git a/src/types/summary/exports.d.ts b/src/types/summary/exports.d.ts index f44277fe613..17d58c19a5b 100644 --- a/src/types/summary/exports.d.ts +++ b/src/types/summary/exports.d.ts @@ -1,10 +1,10 @@ -export type {PrebidJS} from '../../prebidGlobal.ts'; +export type { PrebidJS } from '../../prebidGlobal.ts'; // Type definitions (besides the prebid global) that may be useful to consumers, -export type {Bid, VideoBid, BannerBid, NativeBid} from '../../bidfactory.ts'; -export type {BidRequest, BidderRequest} from '../../adapterManager.ts'; -export type {Config} from '../../config.ts'; -export type {AdUnit, AdUnitDefinition, AdUnitBid} from '../../adUnits.ts' -export type {ORTBRequest, ORTBImp} from '../ortb/request.d.ts'; -export type {ORTBResponse} from '../ortb/response.d.ts'; -export type {NativeRequest as ORTBNativeRequest} from '../ortb/native.d.ts'; -export type {Event, EventRecord, EventPayload, EventHandler} from '../../events.ts'; +export type { Bid, VideoBid, BannerBid, NativeBid } from '../../bidfactory.ts'; +export type { BidRequest, BidderRequest } from '../../adapterManager.ts'; +export type { Config } from '../../config.ts'; +export type { AdUnit, AdUnitDefinition, AdUnitBid } from '../../adUnits.ts' +export type { ORTBRequest, ORTBImp } from '../ortb/request.d.ts'; +export type { ORTBResponse } from '../ortb/response.d.ts'; +export type { NativeRequest as ORTBNativeRequest } from '../ortb/native.d.ts'; +export type { Event, EventRecord, EventPayload, EventHandler } from '../../events.ts'; diff --git a/src/userSync.ts b/src/userSync.ts index 6c62fb36833..0d20e0f9a3a 100644 --- a/src/userSync.ts +++ b/src/userSync.ts @@ -5,23 +5,23 @@ import { import { config } from './config.js'; import { getCoreStorageManager } from './storageManager.js'; -import {isActivityAllowed, registerActivityControl} from './activities/rules.js'; -import {ACTIVITY_SYNC_USER} from './activities/activities.js'; +import { isActivityAllowed, registerActivityControl } from './activities/rules.js'; +import { ACTIVITY_SYNC_USER } from './activities/activities.js'; import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE, ACTIVITY_PARAM_SYNC_TYPE, ACTIVITY_PARAM_SYNC_URL } from './activities/params.js'; -import {MODULE_TYPE_BIDDER} from './activities/modules.js'; -import {activityParams} from './activities/activityParams.js'; -import type {BidderCode} from "./types/common.d.ts"; +import { MODULE_TYPE_BIDDER } from './activities/modules.js'; +import { activityParams } from './activities/activityParams.js'; +import type { BidderCode } from "./types/common.d.ts"; export type SyncType = 'image' | 'iframe'; type SyncConfig = { bidders: '*' | BidderCode[]; filter: 'include' | 'exclude' } -type FilterSettings = {[K in SyncType | 'all']?: SyncConfig}; +type FilterSettings = { [K in SyncType | 'all']?: SyncConfig }; export interface UserSyncConfig { /** @@ -122,13 +122,13 @@ export function newUserSync(deps) { deps.regRule(ACTIVITY_SYNC_USER, 'userSync config', (params) => { if (!usConfig.syncEnabled) { - return {allow: false, reason: 'syncs are disabled'} + return { allow: false, reason: 'syncs are disabled' } } if (params[ACTIVITY_PARAM_COMPONENT_TYPE] === MODULE_TYPE_BIDDER) { const syncType = params[ACTIVITY_PARAM_SYNC_TYPE]; const bidder = params[ACTIVITY_PARAM_COMPONENT_NAME]; if (!publicApi.canBidderRegisterSync(syncType, bidder)) { - return {allow: false, reason: `${syncType} syncs are not enabled for ${bidder}`} + return { allow: false, reason: `${syncType} syncs are not enabled for ${bidder}` } } } }); diff --git a/src/utils.js b/src/utils.js index ec30b934a49..f9ca35de8a7 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,14 +1,14 @@ -import {config} from './config.js'; +import { config } from './config.js'; -import {EVENTS} from './constants.js'; -import {PbPromise} from './utils/promise.js'; +import { EVENTS } from './constants.js'; +import { PbPromise } from './utils/promise.js'; import deepAccess from 'dlv/index.js'; -import {isArray, isFn, isStr, isPlainObject} from './utils/objects.js'; +import { isArray, isFn, isStr, isPlainObject } from './utils/objects.js'; export { deepAccess }; export { dset as deepSetValue } from 'dset'; export * from './utils/objects.js' -export {getWinDimensions, resetWinDimensions, getScreenOrientation} from './utils/winDimensions.js'; +export { getWinDimensions, resetWinDimensions, getScreenOrientation } from './utils/winDimensions.js'; const consoleExists = Boolean(window.console); const consoleLogExists = Boolean(consoleExists && window.console.log); const consoleInfoExists = Boolean(consoleExists && window.console.info); @@ -164,7 +164,7 @@ export function parseGPTSingleSizeArray(singleSize) { } export function sizeTupleToRtbSize(size) { - return {w: size[0], h: size[1]}; + return { w: size[0], h: size[1] }; } // Parse a GPT style single size array, (i.e [300, 250]) @@ -206,6 +206,18 @@ export function canAccessWindowTop() { } } +/** + * Returns the window to use for fingerprinting reads: win if provided, otherwise top or self. + * @param {Window} [win] + * @returns {Window} + */ +export function getFallbackWindow(win) { + if (win) { + return win; + } + return canAccessWindowTop() ? internal.getWindowTop() : internal.getWindowSelf(); +} + /** * Wrappers to console.(log | info | warn | error). Takes N arguments, the same as the native methods */ @@ -650,7 +662,7 @@ export function replaceMacros(str, subs) { } export function replaceAuctionPrice(str, cpm) { - return replaceMacros(str, {AUCTION_PRICE: cpm}) + return replaceMacros(str, { AUCTION_PRICE: cpm }) } export function replaceClickThrough(str, clicktag) { @@ -808,7 +820,7 @@ export function isAdUnitCodeMatchingSlot(slot) { * @return {string} warning message to display when condition is met */ export function unsupportedBidderMessage(adUnit, bidder) { - const mediaType = Object.keys(adUnit.mediaTypes || {'banner': 'banner'}).join(', '); + const mediaType = Object.keys(adUnit.mediaTypes || { 'banner': 'banner' }).join(', '); return ` ${adUnit.code} is a ${mediaType} ad unit @@ -1125,7 +1137,7 @@ export function getUnixTimestampFromNow(timeValue = 0, timeUnit = 'd') { */ export function convertObjectToArray(obj) { return Object.keys(obj).map(key => { - return {[key]: obj[key]}; + return { [key]: obj[key] }; }); } diff --git a/src/utils/cpm.js b/src/utils/cpm.js index 7dfabbe53be..f0206486186 100644 --- a/src/utils/cpm.js +++ b/src/utils/cpm.js @@ -1,8 +1,8 @@ -import {auctionManager} from '../auctionManager.js'; -import {bidderSettings} from '../bidderSettings.js'; -import {logError} from '../utils.js'; +import { auctionManager } from '../auctionManager.js'; +import { bidderSettings } from '../bidderSettings.js'; +import { logError } from '../utils.js'; -export function adjustCpm(cpm, bidResponse, bidRequest, {index = auctionManager.index, bs = bidderSettings} = {}) { +export function adjustCpm(cpm, bidResponse, bidRequest, { index = auctionManager.index, bs = bidderSettings } = {}) { bidRequest = bidRequest || index.getBidRequest(bidResponse); const adapterCode = bidResponse?.adapterCode; const bidderCode = bidResponse?.bidderCode || bidRequest?.bidder; diff --git a/src/utils/objects.ts b/src/utils/objects.ts index 90674d366d6..ca4ac3f41c8 100644 --- a/src/utils/objects.ts +++ b/src/utils/objects.ts @@ -1,6 +1,6 @@ -import {klona} from "klona/json"; -import type {AnyFunction} from "../types/functions.d.ts"; -import type {Repeat} from "../types/tuples.d.ts"; +import { klona } from "klona/json"; +import type { AnyFunction } from "../types/functions.d.ts"; +import type { Repeat } from "../types/tuples.d.ts"; export function deepClone(obj: T): T { return (klona(obj) || {}) as T; diff --git a/src/utils/perfMetrics.ts b/src/utils/perfMetrics.ts index 78b9cff2534..c8778f48e16 100644 --- a/src/utils/perfMetrics.ts +++ b/src/utils/perfMetrics.ts @@ -1,8 +1,8 @@ -import {config} from '../config.js'; -import type {AnyFunction, Wraps} from "../types/functions.d.ts"; -import {type BeforeHook, type BeforeHookParams, type HookType, Next} from "../hook.ts"; -import type {addBidResponse} from "../auction.ts"; -import type {PrivRequestBidsOptions, StartAuctionOptions} from "../prebid.ts"; +import { config } from '../config.js'; +import type { AnyFunction, Wraps } from "../types/functions.d.ts"; +import { type BeforeHook, type BeforeHookParams, type HookType, Next } from "../hook.ts"; +import type { addBidResponse } from "../auction.ts"; +import type { PrivRequestBidsOptions, StartAuctionOptions } from "../prebid.ts"; export const CONFIG_TOGGLE = 'performanceMetrics'; const getTime = window.performance && window.performance.now ? () => window.performance.now() : () => Date.now(); @@ -44,9 +44,9 @@ function wrapFn(fn: F, before?: () => void, after?: () => }; } -export function metricsFactory({now = getTime, mkNode = makeNode, mkTimer = makeTimer, mkRenamer = (rename) => rename, nodes = NODES} = {}) { +export function metricsFactory({ now = getTime, mkNode = makeNode, mkTimer = makeTimer, mkRenamer = (rename) => rename, nodes = NODES } = {}) { return function newMetrics() { - function makeMetrics(self, rename = (n) => ({forEach(fn) { fn(n); }})) { + function makeMetrics(self, rename = (n) => ({ forEach(fn) { fn(n); } })) { rename = mkRenamer(rename); function accessor(slot) { @@ -248,18 +248,18 @@ export function metricsFactory({now = getTime, mkNode = makeNode, mkTimer = make * } * ``` */ - function fork({propagate = true, stopPropagation = false, includeGroups = false}: PropagationOptions = {}): Metrics { - return makeMetrics(mkNode([[self, {propagate, stopPropagation, includeGroups}]]), rename); + function fork({ propagate = true, stopPropagation = false, includeGroups = false }: PropagationOptions = {}): Metrics { + return makeMetrics(mkNode([[self, { propagate, stopPropagation, includeGroups }]]), rename); } /** * Join `otherMetrics` with these; all metrics from `otherMetrics` will (by default) be propagated here, * and all metrics from here will be included in `otherMetrics`. */ - function join(otherMetrics: Metrics, {propagate = true, stopPropagation = false, includeGroups = false}: PropagationOptions = {}): void { + function join(otherMetrics: Metrics, { propagate = true, stopPropagation = false, includeGroups = false }: PropagationOptions = {}): void { const other = nodes.get(otherMetrics); if (other != null) { - other.addParent(self, {propagate, stopPropagation, includeGroups}); + other.addParent(self, { propagate, stopPropagation, includeGroups }); } } @@ -329,7 +329,7 @@ function makeNode(parents) { newSibling() { return makeNode(parents.slice()); }, - dfWalk({visit, follow = () => true, visited = new Set(), inEdge} = {} as any) { + dfWalk({ visit, follow = () => true, visited = new Set(), inEdge } = {} as any) { let res; if (!visited.has(this)) { visited.add(this); @@ -337,7 +337,7 @@ function makeNode(parents) { if (res != null) return res; for (const [parent, outEdge] of parents) { if (follow(inEdge, outEdge)) { - res = parent.dfWalk({visit, follow, visited, inEdge: outEdge}); + res = parent.dfWalk({ visit, follow, visited, inEdge: outEdge }); if (res != null) return res; } } @@ -349,19 +349,19 @@ function makeNode(parents) { const nullMetrics: Metrics = (() => { const nop = function () {}; const empty = () => ({}); - const none = {forEach: nop}; + const none = { forEach: nop }; const nullTimer = () => null; nullTimer.stopBefore = (fn) => fn; nullTimer.stopAfter = (fn) => fn; const nullNode = Object.defineProperties( - {dfWalk: nop, newSibling: () => nullNode, addParent: nop}, - Object.fromEntries(['metrics', 'timestamps', 'groups'].map(prop => [prop, {get: empty}]))); + { dfWalk: nop, newSibling: () => nullNode, addParent: nop }, + Object.fromEntries(['metrics', 'timestamps', 'groups'].map(prop => [prop, { get: empty }]))); return metricsFactory({ now: () => 0, mkNode: () => nullNode as any, mkRenamer: () => () => none, mkTimer: () => nullTimer, - nodes: {get: nop, set: nop} as unknown as Map + nodes: { get: nop, set: nop } as unknown as Map })(); })(); diff --git a/src/utils/prerendering.ts b/src/utils/prerendering.ts index 088f98f7a41..eab2bb14eda 100644 --- a/src/utils/prerendering.ts +++ b/src/utils/prerendering.ts @@ -1,6 +1,6 @@ -import {logInfo} from '../utils.js'; -import type {AnyFunction} from "../types/functions.d.ts"; -import type {UnwrapPromise, ToPromise} from "./promise.ts"; +import { logInfo } from '../utils.js'; +import type { AnyFunction } from "../types/functions.d.ts"; +import type { UnwrapPromise, ToPromise } from "./promise.ts"; /** * Returns a wrapper around fn that delays execution until the page if activated, if it was prerendered and isDelayEnabled returns true. @@ -13,7 +13,7 @@ export function delayIfPrerendering(isDelayEnabled: () => document.addEventListener('prerenderingchange', () => { logInfo(`Auctions were suspended while page was prerendering`) resolve(fn.apply(this, args)) - }, {once: true}) + }, { once: true }) }) } else { return Promise.resolve>>(fn.apply(this, args)); diff --git a/src/utils/promise.ts b/src/utils/promise.ts index 2da4ea53e2d..93bfb02e731 100644 --- a/src/utils/promise.ts +++ b/src/utils/promise.ts @@ -1,5 +1,5 @@ -import {GreedyPromise, greedySetTimeout} from '../../libraries/greedy/greedyPromise.js'; -import {getGlobal} from '../prebidGlobal.js'; +import { GreedyPromise, greedySetTimeout } from '../../libraries/greedy/greedyPromise.js'; +import { getGlobal } from '../prebidGlobal.js'; declare module '../prebidGlobal' { interface PrebidJS { @@ -35,7 +35,7 @@ export type ToPromise = Promise>; /** * @returns a {promise, resolve, reject} trio where `promise` is resolved by calling `resolve` or `reject`. */ -export function defer({promiseFactory = (resolver) => new PbPromise(resolver) as Promise}: { +export function defer({ promiseFactory = (resolver) => new PbPromise(resolver) as Promise }: { promiseFactory?: (...args: ConstructorParameters>) => Promise } = {}): Defer { function invoker(delegate) { diff --git a/src/utils/ttlCollection.ts b/src/utils/ttlCollection.ts index 8ec43f231e5..38e6ecaf435 100644 --- a/src/utils/ttlCollection.ts +++ b/src/utils/ttlCollection.ts @@ -1,6 +1,6 @@ -import {PbPromise} from './promise.js'; -import {binarySearch, logError, timestamp} from '../utils.js'; -import {setFocusTimeout} from './focusTimeout.js'; +import { PbPromise } from './promise.js'; +import { binarySearch, logError, timestamp } from '../utils.js'; +import { setFocusTimeout } from './focusTimeout.js'; export type TTLCollection = ReturnType>; diff --git a/src/utils/winDimensions.js b/src/utils/winDimensions.js index 2759e56eba6..af25f3b2b25 100644 --- a/src/utils/winDimensions.js +++ b/src/utils/winDimensions.js @@ -1,5 +1,5 @@ -import {canAccessWindowTop, internal as utilsInternals} from '../utils.js'; -import {CachedApiWrapper} from './cachedApiWrapper.js'; +import { canAccessWindowTop, internal as utilsInternals } from '../utils.js'; +import { CachedApiWrapper } from './cachedApiWrapper.js'; const CHECK_INTERVAL_MS = 20; diff --git a/src/utils/yield.ts b/src/utils/yield.ts index 57b198053e9..0ac37b9d6b5 100644 --- a/src/utils/yield.ts +++ b/src/utils/yield.ts @@ -1,4 +1,4 @@ -import {PbPromise} from "./promise.ts"; +import { PbPromise } from "./promise.ts"; declare module '../prebidGlobal' { interface PrebidJS { diff --git a/src/video.ts b/src/video.ts index 020ee6a1bd2..14a18a6b4bd 100644 --- a/src/video.ts +++ b/src/video.ts @@ -1,52 +1,52 @@ -import {isArrayOfNums, isInteger, isNumber, isStr, logError, logWarn} from './utils.js'; -import {config} from './config.js'; -import {hook} from './hook.js'; -import {auctionManager} from './auctionManager.js'; -import type {VideoBid} from "./bidfactory.ts"; -import {ADPOD, type BaseMediaType} from "./mediaTypes.ts"; -import type {ORTBImp} from "./types/ortb/request.d.ts"; -import type {Size} from "./types/common.d.ts"; -import type {AdUnitDefinition} from "./adUnits.ts"; +import { isArrayOfNums, isInteger, isNumber, isStr, logError, logWarn } from './utils.js'; +import { config } from './config.js'; +import { hook } from './hook.js'; +import { auctionManager } from './auctionManager.js'; +import type { VideoBid } from "./bidfactory.ts"; +import { ADPOD, type BaseMediaType } from "./mediaTypes.ts"; +import type { ORTBImp } from "./types/ortb/request.d.ts"; +import type { Size } from "./types/common.d.ts"; +import type { AdUnitDefinition } from "./adUnits.ts"; -import {getGlobalVarName} from "./buildOptions.ts"; +import { getGlobalVarName } from "./buildOptions.ts"; export const OUTSTREAM = 'outstream'; export const INSTREAM = 'instream'; const ORTB_PARAMS = [ - [ 'mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string') ], - [ 'minduration', isInteger ], - [ 'maxduration', isInteger ], - [ 'startdelay', isInteger ], - [ 'maxseq', isInteger ], - [ 'poddur', isInteger ], - [ 'protocols', isArrayOfNums ], - [ 'w', isInteger ], - [ 'h', isInteger ], - [ 'podid', isStr ], - [ 'podseq', isInteger ], - [ 'rqddurs', isArrayOfNums ], - [ 'placement', isInteger ], // deprecated, see plcmt - [ 'plcmt', isInteger ], - [ 'linearity', isInteger ], - [ 'skip', value => [1, 0].includes(value) ], - [ 'skipmin', isInteger ], - [ 'skipafter', isInteger ], - [ 'sequence', isInteger ], // deprecated - [ 'slotinpod', isInteger ], - [ 'mincpmpersec', isNumber ], - [ 'battr', isArrayOfNums ], - [ 'maxextended', isInteger ], - [ 'minbitrate', isInteger ], - [ 'maxbitrate', isInteger ], - [ 'boxingallowed', isInteger ], - [ 'playbackmethod', isArrayOfNums ], - [ 'playbackend', isInteger ], - [ 'delivery', isArrayOfNums ], - [ 'pos', isInteger ], - [ 'api', isArrayOfNums ], - [ 'companiontype', isArrayOfNums ], - [ 'poddedupe', isArrayOfNums ] + ['mimes', value => Array.isArray(value) && value.length > 0 && value.every(v => typeof v === 'string')], + ['minduration', isInteger], + ['maxduration', isInteger], + ['startdelay', isInteger], + ['maxseq', isInteger], + ['poddur', isInteger], + ['protocols', isArrayOfNums], + ['w', isInteger], + ['h', isInteger], + ['podid', isStr], + ['podseq', isInteger], + ['rqddurs', isArrayOfNums], + ['placement', isInteger], // deprecated, see plcmt + ['plcmt', isInteger], + ['linearity', isInteger], + ['skip', value => [1, 0].includes(value)], + ['skipmin', isInteger], + ['skipafter', isInteger], + ['sequence', isInteger], // deprecated + ['slotinpod', isInteger], + ['mincpmpersec', isNumber], + ['battr', isArrayOfNums], + ['maxextended', isInteger], + ['minbitrate', isInteger], + ['maxbitrate', isInteger], + ['boxingallowed', isInteger], + ['playbackmethod', isArrayOfNums], + ['playbackend', isInteger], + ['delivery', isArrayOfNums], + ['pos', isInteger], + ['api', isArrayOfNums], + ['companiontype', isArrayOfNums], + ['poddedupe', isArrayOfNums] ] as const; /** @@ -104,7 +104,7 @@ export function fillVideoDefaults(adUnit: AdUnitDefinition) { /** * Validate that the assets required for video context are present on the bid */ -export function isValidVideoBid(bid: VideoBid, {index = auctionManager.index} = {}): boolean { +export function isValidVideoBid(bid: VideoBid, { index = auctionManager.index } = {}): boolean { const videoMediaType = index.getMediaTypes(bid)?.video; const context = videoMediaType && videoMediaType?.context; const useCacheKey = videoMediaType && videoMediaType?.useCacheKey; diff --git a/src/videoCache.ts b/src/videoCache.ts index b63baf7dd43..46640d40370 100644 --- a/src/videoCache.ts +++ b/src/videoCache.ts @@ -9,12 +9,12 @@ * This trickery helps integrate with ad servers, which set character limits on request params. */ -import {ajaxBuilder} from './ajax.js'; -import {config} from './config.js'; -import {auctionManager} from './auctionManager.js'; -import {generateUUID, logError, logWarn} from './utils.js'; -import {addBidToAuction} from './auction.js'; -import type {VideoBid} from "./bidfactory.ts"; +import { ajaxBuilder } from './ajax.js'; +import { config } from './config.js'; +import { auctionManager } from './auctionManager.js'; +import { generateUUID, logError, logWarn } from './utils.js'; +import { addBidToAuction } from './auction.js'; +import type { VideoBid } from "./bidfactory.ts"; /** * Might be useful to be configurable in the future @@ -116,7 +116,7 @@ declare module './config' { * * @return {Object|null} - The payload to be sent to the prebid-server endpoints, or null if the bid can't be converted cleanly. */ -function toStorageRequest(bid, {index = auctionManager.index} = {}) { +function toStorageRequest(bid, { index = auctionManager.index } = {}) { const vastValue = getVastXml(bid); const auction = index.getAuction(bid); const ttlWithBuffer = Number(bid.ttl) + ttlBufferInSeconds; @@ -243,7 +243,7 @@ export function storeBatch(batch) { logError(`expected ${batch.length} cache IDs, got ${cacheIds.length} instead`) } else { cacheIds.forEach((cacheId, i) => { - const {auctionInstance, bidResponse, afterBidAdded} = batch[i]; + const { auctionInstance, bidResponse, afterBidAdded } = batch[i]; if (cacheId.uuid === '') { logWarn(`Supplied video cache key was already in use by Prebid Cache; caching attempt was rejected. Video bid must be discarded.`); } else { @@ -258,7 +258,7 @@ export function storeBatch(batch) { let batchSize, batchTimeout, cleanupHandler; if (FEATURES.VIDEO || FEATURES.AUDIO) { - config.getConfig('cache', ({cache}) => { + config.getConfig('cache', ({ cache }) => { batchSize = typeof cache.batchSize === 'number' && cache.batchSize > 0 ? cache.batchSize : 1; @@ -293,7 +293,7 @@ export const batchingCache = (timeout = setTimeout, cache = storeBatch) => { batches.push([]); } - batches[batches.length - 1].push({auctionInstance, bidResponse, afterBidAdded}); + batches[batches.length - 1].push({ auctionInstance, bidResponse, afterBidAdded }); if (!debouncing) { debouncing = true; diff --git a/test/build-logic/disclosure_spec.mjs b/test/build-logic/disclosure_spec.mjs index a6d7d38a5f3..a2e736325b9 100644 --- a/test/build-logic/disclosure_spec.mjs +++ b/test/build-logic/disclosure_spec.mjs @@ -1,6 +1,6 @@ -import {describe, it} from 'mocha'; -import {expect} from 'chai'; -import {getDisclosureUrl} from '../../metadata/storageDisclosure.mjs'; +import { describe, it } from 'mocha'; +import { expect } from 'chai'; +import { getDisclosureUrl } from '../../metadata/storageDisclosure.mjs'; describe('getDisclosureUrl', () => { let gvl; diff --git a/test/build-logic/gvl_spec.mjs b/test/build-logic/gvl_spec.mjs index 95085e68976..666dd3f2513 100644 --- a/test/build-logic/gvl_spec.mjs +++ b/test/build-logic/gvl_spec.mjs @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {describe, it} from 'mocha'; -import {isValidGvlId} from '../../metadata/gvl.mjs'; +import { expect } from 'chai'; +import { describe, it } from 'mocha'; +import { isValidGvlId } from '../../metadata/gvl.mjs'; describe('gvl build time checks', () => { let gvl; diff --git a/test/build-logic/no_3384_spec.mjs b/test/build-logic/no_3384_spec.mjs new file mode 100644 index 00000000000..f5e726acf85 --- /dev/null +++ b/test/build-logic/no_3384_spec.mjs @@ -0,0 +1,47 @@ +import { describe, it } from 'mocha'; +import { expect } from 'chai'; +import { execFileSync } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); + +describe('build hygiene checks', () => { + it('should not contain the forbidden legacy token in LocID files', () => { + const forbiddenToken = ['33', '84'].join(''); + const scopeArgs = [ + 'ls-files', + '--', + ':(glob)modules/**/locId*', + ':(glob)test/spec/**/locId*', + 'docs/modules/locid.md', + 'modules/locIdSystem.md' + ]; + const scopedPaths = execFileSync('git', scopeArgs, { cwd: repoRoot, encoding: 'utf8' }) + .split('\n') + .map(filePath => filePath.trim()) + .filter(Boolean); + + expect(scopedPaths.length, 'No LocID files were selected for the 3384 guard').to.be.greaterThan(0); + + const args = [ + 'grep', + '-n', + '-I', + '-E', + `\\b${forbiddenToken}\\b`, + '--', + ...scopedPaths + ]; + + try { + const output = execFileSync('git', args, { cwd: repoRoot, encoding: 'utf8' }); + expect(output.trim(), `Unexpected ${forbiddenToken} matches:\n${output}`).to.equal(''); + } catch (e) { + if (e?.status === 1) { + return; + } + throw e; + } + }); +}); diff --git a/test/fixtures/fixtures.js b/test/fixtures/fixtures.js index ccf40aee9ab..1722bdb9a14 100644 --- a/test/fixtures/fixtures.js +++ b/test/fixtures/fixtures.js @@ -1,6 +1,6 @@ // jscs:disable import { TARGETING_KEYS } from 'src/constants.js'; -import {createBid} from '../../src/bidfactory.js'; +import { createBid } from '../../src/bidfactory.js'; const utils = require('src/utils.js'); function convertTargetingsFromOldToNew(targetings) { @@ -1289,7 +1289,7 @@ export function getCurrencyRates() { }; } -export function createBidReceived({bidder, cpm, auctionId, responseTimestamp, adUnitCode, adId, status, ttl, requestId, mediaType}) { +export function createBidReceived({ bidder, cpm, auctionId, responseTimestamp, adUnitCode, adId, status, ttl, requestId, mediaType }) { const bid = { 'bidderCode': bidder, 'width': '300', diff --git a/test/helpers/analytics.js b/test/helpers/analytics.js index d36bcf44f64..a2d06d30ac1 100644 --- a/test/helpers/analytics.js +++ b/test/helpers/analytics.js @@ -9,7 +9,7 @@ export function fireEvents(events = [ EVENTS.BID_WON ]) { return events.map((ev, i) => { - ev = Array.isArray(ev) ? ev : [ev, {i: i}]; + ev = Array.isArray(ev) ? ev : [ev, { i: i }]; pbEvents.emit.apply(null, ev) return ev; }); @@ -21,7 +21,7 @@ export function expectEvents(events) { to: { beTrackedBy(trackFn) { events.forEach(([eventType, args]) => { - sinon.assert.calledWithMatch(trackFn, sinon.match({eventType, args})); + sinon.assert.calledWithMatch(trackFn, sinon.match({ eventType, args })); }); }, beBundledTo(bundleFn) { diff --git a/test/helpers/consentData.js b/test/helpers/consentData.js index 3ebb4506704..ec4c7654b3d 100644 --- a/test/helpers/consentData.js +++ b/test/helpers/consentData.js @@ -1,5 +1,5 @@ -import {gdprDataHandler, gppDataHandler} from 'src/adapterManager.js'; -import {PbPromise} from '../../src/utils/promise.js'; +import { gdprDataHandler, gppDataHandler } from 'src/adapterManager.js'; +import { PbPromise } from '../../src/utils/promise.js'; export function mockGdprConsent(sandbox, getConsentData = () => null) { sandbox.stub(gdprDataHandler, 'enabled').get(() => true) diff --git a/test/helpers/fpd.js b/test/helpers/fpd.js index a7afecbd28e..c9f7b8c5484 100644 --- a/test/helpers/fpd.js +++ b/test/helpers/fpd.js @@ -1,7 +1,7 @@ -import {dep, enrichFPD} from 'src/fpd/enrichment.js'; -import {PbPromise} from '../../src/utils/promise.js'; -import {deepClone} from '../../src/utils.js'; -import {gdprDataHandler, uspDataHandler} from '../../src/adapterManager.js'; +import { dep, enrichFPD } from 'src/fpd/enrichment.js'; +import { PbPromise } from '../../src/utils/promise.js'; +import { deepClone } from '../../src/utils.js'; +import { gdprDataHandler, uspDataHandler } from '../../src/adapterManager.js'; export function mockFpdEnrichments(sandbox, overrides = {}) { overrides = Object.assign({}, { diff --git a/test/helpers/global_hooks.js b/test/helpers/global_hooks.js index 3df3d27d032..2458bbb96e0 100644 --- a/test/helpers/global_hooks.js +++ b/test/helpers/global_hooks.js @@ -1,4 +1,4 @@ -import {clearEvents} from '../../src/events.js'; +import { clearEvents } from '../../src/events.js'; window.describe = window.context = ((orig) => { let level = 0; diff --git a/test/helpers/hookSetup.js b/test/helpers/hookSetup.js index 2de35bb1dd4..3df2a150fcb 100644 --- a/test/helpers/hookSetup.js +++ b/test/helpers/hookSetup.js @@ -1,4 +1,4 @@ -import {hook} from '../../src/hook.js'; +import { hook } from '../../src/hook.js'; before(() => { hook.ready(); diff --git a/test/helpers/indexStub.js b/test/helpers/indexStub.js index 5202106c9cf..5b81a817003 100644 --- a/test/helpers/indexStub.js +++ b/test/helpers/indexStub.js @@ -1,6 +1,6 @@ -import {AuctionIndex} from '../../src/auctionIndex.js'; +import { AuctionIndex } from '../../src/auctionIndex.js'; -export function stubAuctionIndex({bidRequests, bidderRequests, adUnits, auctionId = 'mock-auction'}) { +export function stubAuctionIndex({ bidRequests, bidderRequests, adUnits, auctionId = 'mock-auction' }) { if (adUnits == null) { adUnits = [] } diff --git a/test/helpers/index_adapter_utils.js b/test/helpers/index_adapter_utils.js index 6c2391e524a..66396cf38a5 100644 --- a/test/helpers/index_adapter_utils.js +++ b/test/helpers/index_adapter_utils.js @@ -221,7 +221,7 @@ exports.matchBidsOnSize = function(lhs, rhs) { } var lstore = createObjectFromArray(configured); - var rstore = createObjectFromArray(rhs.map(bid => [ bid.banner.w + 'x' + bid.banner.h, bid ])); + var rstore = createObjectFromArray(rhs.map(bid => [bid.banner.w + 'x' + bid.banner.h, bid])); var compared = compareOnKeys(lstore, rstore); var matched = compared.intersection.map(function(pair) { return { configured: pair.left, sent: pair.right, name: pair.name } }); @@ -253,7 +253,7 @@ exports.getBidResponse = function(configuredBids, urlJSON, optionalPriceLevel, o if (typeof optionalPassOnBid[i] !== 'undefined' && typeof optionalPassOnBid[i][j] !== 'undefined' && optionalPassOnBid[i][j]) continue; var bid = {}; - bid.adomain = [ (DefaultAdDoman + adCount).toString() ]; + bid.adomain = [(DefaultAdDoman + adCount).toString()]; bid.adid = (DefaultCreativeID + adCount).toString(); bid.impid = adCount.toString(); bid.id = adCount.toString(); @@ -314,7 +314,7 @@ exports.getExpectedAdaptorResponse = function(configuredBids, asResponse) { } if (typeof expectedResponse[placementCode] === 'undefined') { - expectedResponse[placementCode] = [ result ]; + expectedResponse[placementCode] = [result]; } else { expectedResponse[placementCode].push(result); } diff --git a/test/helpers/pbjs-test-only.js b/test/helpers/pbjs-test-only.js index 758940750a3..87212b4e65f 100644 --- a/test/helpers/pbjs-test-only.js +++ b/test/helpers/pbjs-test-only.js @@ -1,4 +1,4 @@ -import {getGlobal} from '../../src/prebidGlobal.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; export const pbjsTestOnly = { diff --git a/test/helpers/prebidGlobal.js b/test/helpers/prebidGlobal.js index e80dff2577d..5c5a9351e24 100644 --- a/test/helpers/prebidGlobal.js +++ b/test/helpers/prebidGlobal.js @@ -1,4 +1,4 @@ -import {getGlobalVarName} from '../../src/buildOptions.js'; +import { getGlobalVarName } from '../../src/buildOptions.js'; window[getGlobalVarName()] = (window[getGlobalVarName()] || {}); window[getGlobalVarName()].installedModules = (window[getGlobalVarName()].installedModules || []); diff --git a/test/helpers/refererDetectionHelper.js b/test/helpers/refererDetectionHelper.js index 855574e64dd..133d4af8dea 100644 --- a/test/helpers/refererDetectionHelper.js +++ b/test/helpers/refererDetectionHelper.js @@ -67,7 +67,7 @@ export function buildWindowTree(urls, topReferrer = null, canonicalUrl = null, a } win.top = sameOriginAsTop ? topWindow : inaccessibles[0]; - const inWin = {parent: inaccessibles[inaccessibles.length - 1], top: inaccessibles[0]}; + const inWin = { parent: inaccessibles[inaccessibles.length - 1], top: inaccessibles[0] }; if (index === 0) { inWin.top = inWin; } diff --git a/test/helpers/testing-utils.js b/test/helpers/testing-utils.js index 368acfd2b11..2bafd658889 100644 --- a/test/helpers/testing-utils.js +++ b/test/helpers/testing-utils.js @@ -1,4 +1,4 @@ -const {expect} = require('chai'); +const { expect } = require('chai'); const DEFAULT_TIMEOUT = 10000; // allow more time for BrowserStack sessions const utils = { host: (process.env.TEST_SERVER_HOST) ? process.env.TEST_SERVER_HOST : 'localhost', @@ -8,7 +8,7 @@ const utils = { }, waitForElement: async function(elementRef, time = DEFAULT_TIMEOUT) { const element = $(elementRef); - await element.waitForExist({timeout: time}); + await element.waitForExist({ timeout: time }); }, switchFrame: async function(frameRef) { const iframe = await $(frameRef); @@ -27,7 +27,7 @@ const utils = { } } }, - setupTest({url, waitFor, expectGAMCreative = null, nestedIframe = true, pause = 5000, timeout = DEFAULT_TIMEOUT, retries = 3}, name, fn) { + setupTest({ url, waitFor, expectGAMCreative = null, nestedIframe = true, pause = 5000, timeout = DEFAULT_TIMEOUT, retries = 3 }, name, fn) { describe(name, function () { this.retries(retries); before(() => utils.loadAndWaitForElement(url, waitFor, pause, timeout, retries)); diff --git a/test/mocks/analyticsStub.js b/test/mocks/analyticsStub.js index 98e0f56688f..12b7de46792 100644 --- a/test/mocks/analyticsStub.js +++ b/test/mocks/analyticsStub.js @@ -1,4 +1,4 @@ -import {_internal, setDebounceDelay} from '../../libraries/analyticsAdapter/AnalyticsAdapter.js'; +import { _internal, setDebounceDelay } from '../../libraries/analyticsAdapter/AnalyticsAdapter.js'; before(() => { // stub out analytics networking to avoid random events polluting the global xhr mock diff --git a/test/mocks/ortbConverter.js b/test/mocks/ortbConverter.js index 446fac4629a..4adad568de6 100644 --- a/test/mocks/ortbConverter.js +++ b/test/mocks/ortbConverter.js @@ -1,5 +1,5 @@ -import {defaultProcessors} from '../../libraries/ortbConverter/converter.js'; -import {pbsExtensions} from '../../libraries/pbsExtensions/pbsExtensions.js'; +import { defaultProcessors } from '../../libraries/ortbConverter/converter.js'; +import { pbsExtensions } from '../../libraries/pbsExtensions/pbsExtensions.js'; beforeEach(() => { // disable caching of default processors so that tests do not freeze a subset for other tests diff --git a/test/mocks/videoCacheStub.js b/test/mocks/videoCacheStub.js index acae5cd6a32..f60da236cd0 100644 --- a/test/mocks/videoCacheStub.js +++ b/test/mocks/videoCacheStub.js @@ -1,4 +1,4 @@ -import {_internal as videoCache} from 'src/videoCache.js'; +import { _internal as videoCache } from 'src/videoCache.js'; /** * Function which can be called from unit tests to stub out the video cache. diff --git a/test/mocks/xhr.js b/test/mocks/xhr.js index de77fbc0b91..87678f72439 100644 --- a/test/mocks/xhr.js +++ b/test/mocks/xhr.js @@ -1,7 +1,7 @@ -import {getUniqueIdentifierStr} from '../../src/utils.js'; -import {GreedyPromise} from 'libraries/greedy/greedyPromise.js'; -import {fakeXhr} from 'nise'; -import {dep} from 'src/ajax.js'; +import { getUniqueIdentifierStr } from '../../src/utils.js'; +import { GreedyPromise } from 'libraries/greedy/greedyPromise.js'; +import { fakeXhr } from 'nise'; +import { dep } from 'src/ajax.js'; export const xhr = fakeXhr.useFakeXMLHttpRequest(); export const server = mockFetchServer(); @@ -13,7 +13,7 @@ function mockFetchServer() { const sandbox = sinon.createSandbox(); const bodies = new WeakMap(); const requests = []; - const {DONE, UNSENT} = XMLHttpRequest; + const { DONE, UNSENT } = XMLHttpRequest; function makeRequest(resource, options) { const requestBody = options?.body || bodies.get(resource); diff --git a/test/spec/AnalyticsAdapter_spec.js b/test/spec/AnalyticsAdapter_spec.js index 1e92d267838..f6c65d78dd6 100644 --- a/test/spec/AnalyticsAdapter_spec.js +++ b/test/spec/AnalyticsAdapter_spec.js @@ -1,15 +1,15 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import * as events from 'src/events.js'; import { EVENTS } from 'src/constants.js'; -import {server} from 'test/mocks/xhr.js'; -import {disableAjaxForAnalytics, enableAjaxForAnalytics} from '../mocks/analyticsStub.js'; -import {clearEvents} from 'src/events.js'; +import { server } from 'test/mocks/xhr.js'; +import { disableAjaxForAnalytics, enableAjaxForAnalytics } from '../mocks/analyticsStub.js'; +import { clearEvents } from 'src/events.js'; import { DEFAULT_EXCLUDE_EVENTS, DEFAULT_INCLUDE_EVENTS, setDebounceDelay } from '../../libraries/analyticsAdapter/AnalyticsAdapter.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; const BID_WON = EVENTS.BID_WON; const NO_BID = EVENTS.NO_BID; @@ -48,17 +48,17 @@ FEATURE: Analytics Adapters API it(`SHOULD call the endpoint WHEN an event occurs that is to be tracked`, function () { const eventType = BID_WON; - const args = {some: 'data'}; + const args = { some: 'data' }; - adapter.track({eventType, args}); + adapter.track({ eventType, args }); const result = JSON.parse(server.requests[0].requestBody); - sinon.assert.match(result, {args: {some: 'data'}, eventType}) + sinon.assert.match(result, { args: { some: 'data' }, eventType }) }); it(`SHOULD queue the event first and then track it WHEN an event occurs before tracking library is available`, function () { const eventType = BID_WON; - const args = {wat: 'wot'}; + const args = { wat: 'wot' }; events.emit(eventType, args); adapter.enableAnalytics(); @@ -66,7 +66,7 @@ FEATURE: Analytics Adapters API // As now AUCTION_DEBUG is triggered for WARNINGS too, the BID_RESPONSE goes last in the array const index = server.requests.length - 1; const result = JSON.parse(server.requests[index].requestBody); - sinon.assert.match(result, {eventType, args: {wat: 'wot'}}) + sinon.assert.match(result, { eventType, args: { wat: 'wot' } }) }); describe('analyticsLabels', () => { @@ -82,11 +82,11 @@ FEATURE: Analytics Adapters API }) it('should be attached to payloads (type: endpoint)', () => { - events.emit(BID_WON, {foo: 'bar'}); + events.emit(BID_WON, { foo: 'bar' }); adapter.enableAnalytics(); server.requests .map(req => JSON.parse(req.requestBody)) - .forEach(payload => sinon.assert.match(payload, {labels: analyticsLabels, args: sinon.match({analyticsLabels})})) + .forEach(payload => sinon.assert.match(payload, { labels: analyticsLabels, args: sinon.match({ analyticsLabels }) })) }); it('should be attached payloads (type: bundle)', () => { @@ -96,9 +96,9 @@ FEATURE: Analytics Adapters API }) window.analytics = sinon.stub(); try { - events.emit(BID_WON, {foo: 'bar'}) + events.emit(BID_WON, { foo: 'bar' }) adapter.enableAnalytics(); - sinon.assert.calledWith(window.analytics, sinon.match.any, BID_WON, sinon.match({analyticsLabels})) + sinon.assert.calledWith(window.analytics, sinon.match.any, BID_WON, sinon.match({ analyticsLabels })) } finally { delete window.analytics; } @@ -108,32 +108,32 @@ FEATURE: Analytics Adapters API Object.assign(adapter, { track: sinon.stub() }); - events.emit(BID_WON, {foo: 'bar'}); + events.emit(BID_WON, { foo: 'bar' }); adapter.enableAnalytics(); sinon.assert.calledWith(adapter.track, sinon.match({ eventType: BID_WON, - args: sinon.match({analyticsLabels}), + args: sinon.match({ analyticsLabels }), labels: analyticsLabels })) }) it('should not override the "analyticsLabels" property an event payload may have', () => { adapter.track = sinon.stub(); - events.emit(BID_WON, {analyticsLabels: 'not these ones'}); + events.emit(BID_WON, { analyticsLabels: 'not these ones' }); adapter.enableAnalytics(); sinon.assert.calledWith(adapter.track, sinon.match({ - args: {analyticsLabels: 'not these ones'} + args: { analyticsLabels: 'not these ones' } })); }); it('should not modify event payloads when there are no labels', () => { config.resetConfig(); adapter.track = sinon.stub(); - events.emit(BID_WON, {'foo': 'bar'}); + events.emit(BID_WON, { 'foo': 'bar' }); adapter.enableAnalytics(); sinon.assert.calledWith(adapter.track, { labels: {}, - args: {foo: 'bar'}, + args: { foo: 'bar' }, eventType: BID_WON }) }) @@ -199,7 +199,7 @@ FEATURE: Analytics Adapters API Object.values(DEFAULT_INCLUDE_EVENTS).forEach(eventType => { it(`SHOULD call global when a ${eventType} event occurs`, () => { - const args = {more: 'info'}; + const args = { more: 'info' }; adapter.enableAnalytics(); events.emit(eventType, args); @@ -216,7 +216,7 @@ FEATURE: Analytics Adapters API it('SHOULD NOT call global again when adapter.enableAnalytics is called with previous timeout', function () { const eventType = BID_WON; - const args = {call: 'timeout'}; + const args = { call: 'timeout' }; events.emit(eventType, args); adapter.enableAnalytics(); @@ -227,7 +227,7 @@ FEATURE: Analytics Adapters API describe(`AND sampling is enabled\n`, function () { const eventType = BID_WON; - const args = {more: 'info'}; + const args = { more: 'info' }; beforeEach(function () { sinon.stub(Math, 'random').returns(0.5); @@ -247,7 +247,7 @@ FEATURE: Analytics Adapters API expect(server.requests.length).to.equal(1); const result = JSON.parse(server.requests[0].requestBody); - sinon.assert.match(result, {args: {more: 'info'}, eventType: 'bidWon'}) + sinon.assert.match(result, { args: { more: 'info' }, eventType: 'bidWon' }) }); it(`THEN should disable analytics when random number is outside sample range`, function () { @@ -286,16 +286,16 @@ describe('Analytics asynchronous event tracking', () => { }) it('does not call track as long as events are coming', () => { - events.emit(BID_WON, {i: 0}); + events.emit(BID_WON, { i: 0 }); sinon.assert.notCalled(adapter.track); clock.tick(10); - events.emit(BID_WON, {i: 1}); + events.emit(BID_WON, { i: 1 }); sinon.assert.notCalled(adapter.track); clock.tick(10); sinon.assert.notCalled(adapter.track); clock.tick(100); sinon.assert.calledTwice(adapter.track); - sinon.assert.calledWith(adapter.track.firstCall, sinon.match({eventType: BID_WON, args: {i: 0}})); - sinon.assert.calledWith(adapter.track.secondCall, sinon.match({eventType: BID_WON, args: {i: 1}})); + sinon.assert.calledWith(adapter.track.firstCall, sinon.match({ eventType: BID_WON, args: { i: 0 } })); + sinon.assert.calledWith(adapter.track.secondCall, sinon.match({ eventType: BID_WON, args: { i: 1 } })); }); }) diff --git a/test/spec/activities/allowActivites_spec.js b/test/spec/activities/allowActivites_spec.js index cc1c83ec4c9..5e06d46330f 100644 --- a/test/spec/activities/allowActivites_spec.js +++ b/test/spec/activities/allowActivites_spec.js @@ -1,7 +1,7 @@ -import {config} from 'src/config.js'; -import {ruleRegistry} from '../../../src/activities/rules.js'; -import {updateRulesFromConfig} from '../../../modules/allowActivities.js'; -import {activityParams} from '../../../src/activities/activityParams.js'; +import { config } from 'src/config.js'; +import { ruleRegistry } from '../../../src/activities/rules.js'; +import { updateRulesFromConfig } from '../../../modules/allowActivities.js'; +import { activityParams } from '../../../src/activities/activityParams.js'; describe('allowActivities config', () => { const MODULE_TYPE = 'test' @@ -41,7 +41,7 @@ describe('allowActivities config', () => { default: false, rules: [ { - condition({componentName}) { + condition({ componentName }) { return componentName === MODULE_NAME }, allow: true @@ -63,7 +63,7 @@ describe('allowActivities config', () => { it('are tested for their condition', () => { setupActivityConfig({ rules: [{ - condition({flag}) { return flag }, + condition({ flag }) { return flag }, allow: false }] }); @@ -74,7 +74,7 @@ describe('allowActivities config', () => { it('always apply if they have no condition', () => { setupActivityConfig({ - rules: [{allow: false}] + rules: [{ allow: false }] }); expect(isAllowed(ACTIVITY, params)).to.be.false; }); @@ -94,7 +94,7 @@ describe('allowActivities config', () => { it('does not pass private (underscored) parameters to condition', () => { setupActivityConfig({ rules: [{ - condition({_priv}) { return _priv }, + condition({ _priv }) { return _priv }, allow: false }] }); @@ -131,7 +131,7 @@ describe('allowActivities config', () => { setupActivityConfig({ allow: false }); - config.setConfig({allowActivities: {}}); + config.setConfig({ allowActivities: {} }); expect(isAllowed(ACTIVITY, params)).to.be.true; }); }); diff --git a/test/spec/activities/objectGuard_spec.js b/test/spec/activities/objectGuard_spec.js index 3f1474b0c46..7c680d82289 100644 --- a/test/spec/activities/objectGuard_spec.js +++ b/test/spec/activities/objectGuard_spec.js @@ -1,6 +1,6 @@ -import {objectGuard, writeProtectRule} from '../../../libraries/objectGuard/objectGuard.js'; -import {redactRule} from '../../../src/activities/redactor.js'; -import {mergeDeep} from 'src/utils.js'; +import { objectGuard, writeProtectRule } from '../../../libraries/objectGuard/objectGuard.js'; +import { redactRule } from '../../../src/activities/redactor.js'; +import { mergeDeep } from 'src/utils.js'; describe('objectGuard', () => { describe('read rule', () => { @@ -11,23 +11,25 @@ describe('objectGuard', () => { paths: ['foo', 'outer.inner.foo'], name: 'testRule', applies: sinon.stub().callsFake(() => applies), - get(val) { return `repl${val}` }, - } - }) + get(val) { + return `repl${val}`; + }, + }; + }); it('should reject conflicting rules', () => { - const crule = {...rule, paths: ['outer']}; + const crule = { ...rule, paths: ['outer'] }; expect(() => objectGuard([rule, crule])).to.throw(); expect(() => objectGuard([crule, rule])).to.throw(); }); it('should preserve object identity', () => { - const guard = objectGuard([rule])({outer: {inner: {foo: 'bar'}}}); + const guard = objectGuard([rule])({ outer: { inner: { foo: 'bar' } } }); expect(guard.outer).to.equal(guard.outer); expect(guard.outer.inner).to.equal(guard.outer.inner); - }) + }); it('can prevent top level read access', () => { - const obj = objectGuard([rule])({'foo': 1, 'other': 2}); + const obj = objectGuard([rule])({ 'foo': 1, 'other': 2 }); expect(obj).to.eql({ foo: 'repl1', other: 2 @@ -40,19 +42,19 @@ describe('objectGuard', () => { }); it('allows concurrent reads', () => { - const obj = {'foo': 'bar'}; + const obj = { 'foo': 'bar' }; const guarded = objectGuard([rule])(obj); obj.foo = 'baz'; expect(guarded.foo).to.eql('replbaz'); - }) + }); it('does not prevent access if applies returns false', () => { applies = false; - const obj = objectGuard([rule])({foo: 1}); + const obj = objectGuard([rule])({ foo: 1 }); expect(obj).to.eql({ foo: 1 }); - }) + }); it('can prevent nested property access', () => { const obj = objectGuard([rule])({ @@ -78,13 +80,13 @@ describe('objectGuard', () => { foo: 3 } } - }) + }); }); it('prevents nested property access when a parent property is protected', () => { - const guard = objectGuard([rule])({foo: {inner: 'value'}}); + const guard = objectGuard([rule])({ foo: { inner: 'value' } }); expect(guard.inner?.value).to.not.exist; - }) + }); it('does not call applies more than once', () => { JSON.stringify(objectGuard([rule])({ @@ -96,7 +98,7 @@ describe('objectGuard', () => { } })); expect(rule.applies.callCount).to.equal(1); - }) + }); }); describe('write protection', () => { @@ -114,70 +116,119 @@ describe('objectGuard', () => { applies = false; const obj = {}; const guard = objectGuard([rule])(obj); - mergeDeep(guard, {foo: {nested: 'item'}}); - expect(obj.foo).to.eql({nested: 'item'}); + mergeDeep(guard, { foo: { nested: 'item' } }); + expect(obj.foo).to.eql({ nested: 'item' }); + }); + + it('should handle circular references in guarded properties', () => { + applies = false; + const obj = { + foo: {} + }; + const guard = objectGuard([rule])(obj); + guard.foo.inner = guard.foo; + expect(guard).to.eql({ + foo: { + inner: guard.foo + } + }); + }); + + it('should handle circular references in unguarded properties', () => { + const obj = {}; + const guard = objectGuard([rule])(obj); + const val = {}; + val.circular = val; + guard.prop = val; + expect(guard).to.eql({ + prop: val + }) }); + it('should allow for deferred modification', () => { + const obj = {}; + const guard = objectGuard([rule])(obj); + const prop = {}; + guard.prop = prop; + prop.val = 'foo'; + expect(obj).to.eql({ + prop: { + val: 'foo' + } + }); + }); + + it('should not choke on immutable objects', () => { + const obj = {}; + const guard = objectGuard([rule])(obj); + guard.prop = Object.freeze({ val: 'foo' }); + expect(obj).to.eql({ + prop: { + val: 'foo' + } + }) + }) + it('should reject conflicting rules', () => { - const crule = {...rule, paths: ['outer']}; + const crule = { ...rule, paths: ['outer'] }; expect(() => objectGuard([rule, crule])).to.throw(); expect(() => objectGuard([crule, rule])).to.throw(); }); it('should preserve object identity', () => { - const guard = objectGuard([rule])({outer: {inner: {foo: 'bar'}}}); + const guard = objectGuard([rule])({ outer: { inner: { foo: 'bar' } } }); expect(guard.outer).to.equal(guard.outer); expect(guard.outer.inner).to.equal(guard.outer.inner); - }) + }); it('does not mess up array reads', () => { - const guard = objectGuard([rule])({foo: [{bar: 'baz'}]}); - expect(guard.foo).to.eql([{bar: 'baz'}]); - }) + const guard = objectGuard([rule])({ foo: [{ bar: 'baz' }] }); + expect(guard.foo).to.eql([{ bar: 'baz' }]); + }); it('prevents array modification', () => { - const obj = {foo: ['value']}; + const obj = { foo: ['value'] }; const guard = objectGuard([rule])(obj); guard.foo.pop(); guard.foo.push('test'); expect(obj.foo).to.eql(['value']); - }) + }); it('allows array modification when not applicable', () => { applies = false; - const obj = {foo: ['value']}; + const obj = { foo: ['value'] }; const guard = objectGuard([rule])(obj); guard.foo.pop(); guard.foo.push('test'); expect(obj.foo).to.eql(['test']); - }) + }); it('should prevent top-level writes', () => { - const obj = {bar: {nested: 'val'}, other: 'val'}; + const obj = { bar: { nested: 'val' }, other: 'val' }; const guard = objectGuard([rule])(obj); guard.foo = 'denied'; guard.bar.nested = 'denied'; guard.bar.other = 'denied'; guard.other = 'allowed'; - expect(guard).to.eql({bar: {nested: 'val'}, other: 'allowed'}); + expect(guard).to.eql({ bar: { nested: 'val' }, other: 'allowed' }); }); it('should not prevent no-op writes', () => { - const guard = objectGuard([rule])({foo: {some: 'value'}}); - guard.foo = {some: 'value'}; + const guard = objectGuard([rule])({ foo: { some: 'value' } }); + guard.foo = { some: 'value' }; sinon.assert.notCalled(rule.applies); - }) + }); it('should prevent top-level deletes', () => { - const obj = {foo: {nested: 'val'}, bar: 'val'}; + const obj = { foo: { nested: 'val' }, bar: 'val' }; const guard = objectGuard([rule])(obj); delete guard.foo.nested; delete guard.bar; - expect(guard).to.eql({foo: {nested: 'val'}, bar: 'val'}); - }) + expect(guard).to.eql({ foo: { nested: 'val' }, bar: 'val' }); + }); it('should prevent nested writes', () => { - const obj = {outer: {inner: {bar: {nested: 'val'}, other: 'val'}}}; + const obj = { outer: { inner: { bar: { nested: 'val' }, other: 'val' } } }; const guard = objectGuard([rule])(obj); guard.outer.inner.bar.other = 'denied'; guard.outer.inner.bar.nested = 'denied'; @@ -192,71 +243,71 @@ describe('objectGuard', () => { other: 'allowed' } } - }) + }); }); it('should prevent writes if upper levels are protected', () => { - const obj = {foo: {inner: {}}}; + const obj = { foo: { inner: {} } }; const guard = objectGuard([rule])(obj); guard.foo.inner.prop = 'value'; - expect(obj).to.eql({foo: {inner: {}}}); - }) + expect(obj).to.eql({ foo: { inner: {} } }); + }); it('should prevent deletes if a higher level property is protected', () => { - const obj = {foo: {inner: {prop: 'value'}}}; + const obj = { foo: { inner: { prop: 'value' } } }; const guard = objectGuard([rule])(obj); delete guard.foo.inner.prop; - expect(obj).to.eql({foo: {inner: {prop: 'value'}}}); - }) + expect(obj).to.eql({ foo: { inner: { prop: 'value' } } }); + }); it('should clean up top-level writes that would result in inner properties changing', () => { - const guard = objectGuard([rule])({outer: {inner: {bar: 'baz'}}}); - guard.outer = {inner: {bar: 'baz', foo: 'baz', prop: 'allowed'}}; - expect(guard).to.eql({outer: {inner: {bar: 'baz', prop: 'allowed'}}}); - }) + const guard = objectGuard([rule])({ outer: { inner: { bar: 'baz' } } }); + guard.outer = { inner: { bar: 'baz', foo: 'baz', prop: 'allowed' } }; + expect(guard).to.eql({ outer: { inner: { bar: 'baz', prop: 'allowed' } } }); + }); it('should not prevent writes that are not protected', () => { const obj = {}; const guard = objectGuard([rule])(obj); guard.outer = { test: 'value' - } + }; expect(obj.outer.test).to.eql('value'); - }) + }); it('should not choke on type mismatch: overwrite object with scalar', () => { - const obj = {outer: {inner: {}}}; + const obj = { outer: { inner: {} } }; const guard = objectGuard([rule])(obj); guard.outer = null; - expect(obj).to.eql({outer: {inner: {}}}); + expect(obj).to.eql({ outer: { inner: {} } }); }); it('should not choke on type mismatch: overwrite scalar with object', () => { - const obj = {outer: null}; + const obj = { outer: null }; const guard = objectGuard([rule])(obj); - guard.outer = {inner: {bar: 'denied', other: 'allowed'}}; - expect(obj).to.eql({outer: {inner: {other: 'allowed'}}}); - }) + guard.outer = { inner: { bar: 'denied', other: 'allowed' } }; + expect(obj).to.eql({ outer: { inner: { other: 'allowed' } } }); + }); it('should prevent nested deletes', () => { - const obj = {outer: {inner: {foo: {nested: 'val'}, bar: 'val'}}}; + const obj = { outer: { inner: { foo: { nested: 'val' }, bar: 'val' } } }; const guard = objectGuard([rule])(obj); delete guard.outer.inner.foo.nested; delete guard.outer.inner.bar; - expect(guard).to.eql({outer: {inner: {foo: {nested: 'val'}, bar: 'val'}}}) + expect(guard).to.eql({ outer: { inner: { foo: { nested: 'val' }, bar: 'val' } } }); }); it('should prevent higher level deletes that would result in inner properties changing', () => { - const guard = objectGuard([rule])({outer: {inner: {bar: 'baz'}}}); + const guard = objectGuard([rule])({ outer: { inner: { bar: 'baz' } } }); delete guard.outer.inner; - expect(guard).to.eql({outer: {inner: {bar: 'baz'}}}); - }) + expect(guard).to.eql({ outer: { inner: { bar: 'baz' } } }); + }); it('should work on null properties', () => { - const obj = {foo: null}; + const obj = { foo: null }; const guard = objectGuard([rule])(obj); guard.foo = 'denied'; - expect(guard).to.eql({foo: null}); + expect(guard).to.eql({ foo: null }); }); }); describe('multiple rules on the same path', () => { @@ -276,7 +327,7 @@ describe('objectGuard', () => { return '2' + val; } }) - ])({foo: 'bar'}); + ])({ foo: 'bar' }); expect(obj.foo).to.eql('21bar'); }); @@ -293,18 +344,18 @@ describe('objectGuard', () => { applies: () => true, }) ]; - }) + }); Object.entries({ 'simple value': 'val', - 'object value': {inner: 'val'} + 'object value': { inner: 'val' } }).forEach(([t, val]) => { it(`can apply them both (on ${t})`, () => { - const obj = objectGuard(rules)({foo: val}); + const obj = objectGuard(rules)({ foo: val }); expect(obj.foo).to.not.exist; - obj.foo = {other: 'val'}; + obj.foo = { other: 'val' }; expect(obj.foo).to.not.exist; - }) - }) - }) - }) + }); + }); + }); + }); }); diff --git a/test/spec/activities/ortbGuard_spec.js b/test/spec/activities/ortbGuard_spec.js index 1384a6c0674..ff2f961277b 100644 --- a/test/spec/activities/ortbGuard_spec.js +++ b/test/spec/activities/ortbGuard_spec.js @@ -1,14 +1,14 @@ -import {ortb2FragmentsGuardFactory, ortb2GuardFactory} from '../../../libraries/objectGuard/ortbGuard.js'; -import {ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE} from '../../../src/activities/params.js'; +import { ortb2FragmentsGuardFactory, ortb2GuardFactory } from '../../../libraries/objectGuard/ortbGuard.js'; +import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE } from '../../../src/activities/params.js'; import { ACTIVITY_ENRICH_EIDS, ACTIVITY_ENRICH_UFPD, ACTIVITY_TRANSMIT_EIDS, ACTIVITY_TRANSMIT_UFPD } from '../../../src/activities/activities.js'; -import {activityParams} from '../../../src/activities/activityParams.js'; -import {deepAccess, deepClone, deepSetValue, mergeDeep} from '../../../src/utils.js'; -import {ORTB_EIDS_PATHS, ORTB_UFPD_PATHS} from '../../../src/activities/redactor.js'; -import {objectGuard, writeProtectRule} from '../../../libraries/objectGuard/objectGuard.js'; +import { activityParams } from '../../../src/activities/activityParams.js'; +import { deepAccess, deepClone, deepSetValue, mergeDeep } from '../../../src/utils.js'; +import { ORTB_EIDS_PATHS, ORTB_UFPD_PATHS } from '../../../src/activities/redactor.js'; +import { objectGuard, writeProtectRule } from '../../../libraries/objectGuard/objectGuard.js'; describe('ortb2Guard', () => { const MOD_TYPE = 'test'; @@ -46,12 +46,12 @@ describe('ortb2Guard', () => { function testPropertiesAreProtected(properties, allowed) { properties.forEach(prop => { it(`should ${allowed ? 'keep' : 'prevent'} additions to ${prop}`, () => { - const orig = [{n: 'orig'}]; + const orig = [{ n: 'orig' }]; const ortb2 = {}; deepSetValue(ortb2, prop, deepClone(orig)); const guard = ortb2Guard(ortb2, activityParams(MOD_TYPE, MOD_NAME)); const mod = {}; - const insert = [{n: 'new'}]; + const insert = [{ n: 'new' }]; deepSetValue(mod, prop, insert); mergeDeep(guard, mod); const actual = deepAccess(ortb2, prop); @@ -63,16 +63,16 @@ describe('ortb2Guard', () => { }); it(`should ${allowed ? 'keep' : 'prevent'} modifications to ${prop}`, () => { - const orig = [{n: 'orig'}]; + const orig = [{ n: 'orig' }]; const ortb2 = {}; deepSetValue(ortb2, prop, orig); const guard = ortb2Guard(ortb2, activityParams(MOD_TYPE, MOD_NAME)); deepSetValue(guard, `${prop}.0.n`, 'new'); const actual = deepAccess(ortb2, prop); if (allowed) { - expect(actual).to.eql([{n: 'new'}]); + expect(actual).to.eql([{ n: 'new' }]); } else { - expect(actual).to.eql([{n: 'orig'}]); + expect(actual).to.eql([{ n: 'orig' }]); } }); }) @@ -103,12 +103,12 @@ describe('ortb2FragmentsGuard', () => { it('should prevent changes to global FPD', () => { const fragments = { global: { - foo: {inner: 'val'} + foo: { inner: 'val' } } } const guard = guardFragments(fragments); guard.global.foo = 'other'; - expect(fragments.global.foo).to.eql({inner: 'val'}); + expect(fragments.global.foo).to.eql({ inner: 'val' }); }); it('should prevent changes to bidder FPD', () => { @@ -121,7 +121,7 @@ describe('ortb2FragmentsGuard', () => { }; const guard = guardFragments(fragments); guard.bidder.A.foo = 'denied'; - expect(fragments.bidder.A).to.eql({foo: 'val'}); + expect(fragments.bidder.A).to.eql({ foo: 'val' }); }); it('should prevent changes to bidder FPD that was not initially there', () => { @@ -129,7 +129,7 @@ describe('ortb2FragmentsGuard', () => { bidder: {} }; const guard = guardFragments(fragments); - guard.bidder.A = {foo: 'denied', other: 'allowed'}; - expect(fragments.bidder.A).to.eql({other: 'allowed'}); + guard.bidder.A = { foo: 'denied', other: 'allowed' }; + expect(fragments.bidder.A).to.eql({ other: 'allowed' }); }); }) diff --git a/test/spec/activities/params_spec.js b/test/spec/activities/params_spec.js index d949cd41cb4..1fc00d7e578 100644 --- a/test/spec/activities/params_spec.js +++ b/test/spec/activities/params_spec.js @@ -4,12 +4,12 @@ import { ACTIVITY_PARAM_COMPONENT_TYPE } from '../../../src/activities/params.js'; import adapterManager from '../../../src/adapterManager.js'; -import {MODULE_TYPE_BIDDER} from '../../../src/activities/modules.js'; -import {activityParams} from '../../../src/activities/activityParams.js'; +import { MODULE_TYPE_BIDDER } from '../../../src/activities/modules.js'; +import { activityParams } from '../../../src/activities/activityParams.js'; describe('activityParams', () => { it('fills out component params', () => { - sinon.assert.match(activityParams('bidder', 'mockBidder', {foo: 'bar'}), { + sinon.assert.match(activityParams('bidder', 'mockBidder', { foo: 'bar' }), { [ACTIVITY_PARAM_COMPONENT]: 'bidder.mockBidder', [ACTIVITY_PARAM_COMPONENT_TYPE]: 'bidder', [ACTIVITY_PARAM_COMPONENT_NAME]: 'mockBidder', @@ -18,7 +18,7 @@ describe('activityParams', () => { }); it('fills out adapterCode', () => { - adapterManager.registerBidAdapter({callBids: sinon.stub(), getSpec: sinon.stub().returns({})}, 'mockBidder') + adapterManager.registerBidAdapter({ callBids: sinon.stub(), getSpec: sinon.stub().returns({}) }, 'mockBidder') adapterManager.aliasBidAdapter('mockBidder', 'mockAlias'); expect(activityParams(MODULE_TYPE_BIDDER, 'mockAlias')[ACTIVITY_PARAM_ADAPTER_CODE]).to.equal('mockBidder'); }); diff --git a/test/spec/activities/redactor_spec.js b/test/spec/activities/redactor_spec.js index e1d565d6d60..57ea96a6fd4 100644 --- a/test/spec/activities/redactor_spec.js +++ b/test/spec/activities/redactor_spec.js @@ -6,14 +6,14 @@ import { ORTB_UFPD_PATHS, redactorFactory, redactRule } from '../../../src/activities/redactor.js'; -import {ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE} from '../../../src/activities/params.js'; +import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE } from '../../../src/activities/params.js'; import { ACTIVITY_TRANSMIT_EIDS, ACTIVITY_TRANSMIT_PRECISE_GEO, ACTIVITY_TRANSMIT_TID, ACTIVITY_TRANSMIT_UFPD } from '../../../src/activities/activities.js'; -import {deepAccess, deepSetValue} from '../../../src/utils.js'; -import {activityParams} from '../../../src/activities/activityParams.js'; +import { deepAccess, deepSetValue } from '../../../src/utils.js'; +import { activityParams } from '../../../src/activities/activityParams.js'; describe('objectTransformer', () => { describe('using dummy rules', () => { @@ -30,7 +30,7 @@ describe('objectTransformer', () => { }); it('runs rule for each path', () => { - const obj = {foo: 'val'}; + const obj = { foo: 'val' }; objectTransformer([rule])({}, obj); sinon.assert.calledWith(run, obj, null, obj, 'foo'); sinon.assert.calledWith(run, obj, 'bar', undefined, 'baz'); @@ -56,15 +56,15 @@ describe('objectTransformer', () => { }); it('does not call apply if session already contains a result for the rule', () => { - objectTransformer([rule])({[rule.name]: false}, {}); + objectTransformer([rule])({ [rule.name]: false }, {}); expect(applies.callCount).to.equal(0); expect(run.callCount).to.equal(0); }) it('passes arguments to applies', () => { run.callsFake((_1, _2, _3, _4, applies) => applies()); - const arg1 = {n: 0}; - const arg2 = {n: 1}; + const arg1 = { n: 0 }; + const arg2 = { n: 1 }; objectTransformer([rule])({}, {}, arg1, arg2); sinon.assert.calledWith(applies, arg1, arg2); }); @@ -95,10 +95,10 @@ describe('objectTransformer', () => { expect(Object.keys(parent)).to.not.include.members([prop]); } } - }).forEach(([t, {get, expectation}]) => { + }).forEach(([t, { get, expectation }]) => { describe(`property ${t}`, () => { it('should work on top level properties', () => { - const obj = {foo: 1, bar: 2}; + const obj = { foo: 1, bar: 2 }; objectTransformer([ redactRule({ name: 'test', @@ -113,7 +113,7 @@ describe('objectTransformer', () => { expectation(obj, 'foo', get(1)); }); it('should work on nested properties', () => { - const obj = {outer: {inner: {foo: 'bar'}, baz: 0}}; + const obj = { outer: { inner: { foo: 'bar' }, baz: 0 } }; objectTransformer([ redactRule({ name: 'test', @@ -134,10 +134,10 @@ describe('objectTransformer', () => { describe('should not run rule if property is', () => { Object.entries({ 'missing': {}, - 'empty array': {foo: []}, - 'empty object': {foo: {}}, - 'null': {foo: null}, - 'undefined': {foo: undefined} + 'empty array': { foo: [] }, + 'empty object': { foo: {} }, + 'null': { foo: null }, + 'undefined': { foo: undefined } }).forEach(([t, obj]) => { it(t, () => { const get = sinon.stub(); @@ -160,14 +160,14 @@ describe('objectTransformer', () => { false: false }).forEach(([t, val]) => { it(t, () => { - const obj = {foo: val}; + const obj = { foo: val }; objectTransformer([redactRule({ name: 'test', paths: ['foo'], applies() { return true }, get(val) { return 'repl' }, })])({}, obj); - expect(obj).to.eql({foo: 'repl'}); + expect(obj).to.eql({ foo: 'repl' }); }) }) }); diff --git a/test/spec/activities/rules_spec.js b/test/spec/activities/rules_spec.js index 2acfae57980..59d16ad9c34 100644 --- a/test/spec/activities/rules_spec.js +++ b/test/spec/activities/rules_spec.js @@ -1,4 +1,4 @@ -import {ruleRegistry} from '../../../src/activities/rules.js'; +import { ruleRegistry } from '../../../src/activities/rules.js'; describe('Activity control rules', () => { const MOCK_ACTIVITY = 'mockActivity'; @@ -27,73 +27,73 @@ describe('Activity control rules', () => { }); it('denies if a rule denies', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false })); expect(isAllowed(MOCK_ACTIVITY, {})).to.be.false; }); it('partitions rules by activity', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false })); expect(isAllowed('other', {})).to.be.true; }); it('passes params to rules', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, (params) => ({allow: params.foo !== 'bar'})); - expect(isAllowed(MOCK_ACTIVITY, {foo: 'notbar'})).to.be.true; - expect(isAllowed(MOCK_ACTIVITY, {foo: 'bar'})).to.be.false; + registerRule(MOCK_ACTIVITY, MOCK_RULE, (params) => ({ allow: params.foo !== 'bar' })); + expect(isAllowed(MOCK_ACTIVITY, { foo: 'notbar' })).to.be.true; + expect(isAllowed(MOCK_ACTIVITY, { foo: 'bar' })).to.be.false; }); it('allows if rules do not opine', () => { registerRule(MOCK_ACTIVITY, MOCK_RULE, () => null); - expect(isAllowed(MOCK_ACTIVITY, {foo: 'bar'})).to.be.true; + expect(isAllowed(MOCK_ACTIVITY, { foo: 'bar' })).to.be.true; }); it('denies if any rule denies', () => { registerRule(MOCK_ACTIVITY, MOCK_RULE, () => null); - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true})); - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false})); - expect(isAllowed(MOCK_ACTIVITY, {foo: 'bar'})).to.be.false; + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true })); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false })); + expect(isAllowed(MOCK_ACTIVITY, { foo: 'bar' })).to.be.false; }); it('allows if higher priority allow rule trumps a lower priority deny rule', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false})); - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true}), 0); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false })); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true }), 0); expect(isAllowed(MOCK_ACTIVITY, {})).to.be.true; }); it('denies if a higher priority deny rule trumps a lower priority allow rule', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true})); - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false}), 0); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true })); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false }), 0); expect(isAllowed(MOCK_ACTIVITY, {})).to.be.false; }); it('can unregister rules', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true})); - const r = registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false}), 0); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true })); + const r = registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false }), 0); expect(isAllowed(MOCK_ACTIVITY, {})).to.be.false; r(); expect(isAllowed(MOCK_ACTIVITY, {})).to.be.true; }) it('logs INFO when explicit allow is found', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true })); isAllowed(MOCK_ACTIVITY, {}); sinon.assert.calledWithMatch(logger.logInfo, new RegExp(MOCK_RULE)); }); it('logs INFO with reason if the rule provides one', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: true, reason: 'because'})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: true, reason: 'because' })); isAllowed(MOCK_ACTIVITY, {}); sinon.assert.calledWithMatch(logger.logInfo, new RegExp(MOCK_RULE), /because/); }); it('logs WARN when a deny is found', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false })); isAllowed(MOCK_ACTIVITY, {}); sinon.assert.calledWithMatch(logger.logWarn, new RegExp(MOCK_RULE)); }); it('logs WARN with reason if the rule provides one', () => { - registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({allow: false, reason: 'fail'})); + registerRule(MOCK_ACTIVITY, MOCK_RULE, () => ({ allow: false, reason: 'fail' })); isAllowed(MOCK_ACTIVITY, {}); sinon.assert.calledWithMatch(logger.logWarn, new RegExp(MOCK_RULE), /fail/); }); diff --git a/test/spec/adUnits_spec.js b/test/spec/adUnits_spec.js index 1723a567c11..2a53f4095c1 100644 --- a/test/spec/adUnits_spec.js +++ b/test/spec/adUnits_spec.js @@ -1,7 +1,7 @@ import 'src/prebid.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; -import {getGlobalVarName} from '../../src/buildOptions.js'; +import { getGlobalVarName } from '../../src/buildOptions.js'; describe('Publisher API _ AdUnits', function () { var assert = require('chai').assert; @@ -100,7 +100,7 @@ describe('Publisher API _ AdUnits', function () { it(`the second adUnits value should be same with the adUnits that is added by ${getGlobalVarName()}.addAdUnits();`, function () { assert.strictEqual(adUnit2.code, '/1996833/slot-2', 'adUnit2 code'); assert.deepEqual(adUnit2.sizes, [[468, 60]], 'adUnit2 sizes'); - assert.deepEqual(adUnit2['ortb2Imp'], {'ext': {'data': {'pbadslot': 'adSlotTest', 'inventory': [4], 'keywords': 'foo,bar', 'visitor': [1, 2, 3]}}}, 'adUnit2 ortb2Imp'); + assert.deepEqual(adUnit2['ortb2Imp'], { 'ext': { 'data': { 'pbadslot': 'adSlotTest', 'inventory': [4], 'keywords': 'foo,bar', 'visitor': [1, 2, 3] } } }, 'adUnit2 ortb2Imp'); assert.strictEqual(bids2[0].bidder, 'rubicon', 'adUnit2 bids1 bidder'); assert.strictEqual(bids2[0].params.rp_account, '4934', 'adUnit2 bids1 params.rp_account'); assert.strictEqual(bids2[0].params.rp_zonesize, '23948-15', 'adUnit2 bids1 params.rp_zonesize'); diff --git a/test/spec/adloader_spec.js b/test/spec/adloader_spec.js index f6574e21eda..0a4b244b04c 100644 --- a/test/spec/adloader_spec.js +++ b/test/spec/adloader_spec.js @@ -90,7 +90,7 @@ describe('adLoader', function () { } } }; - const attrs = {'z': 'A', 'y': 2}; + const attrs = { 'z': 'A', 'y': 2 }; const script = adLoader.loadExternalScript('someUrl', MODULE_TYPE_PREBID, 'debugging', undefined, doc, attrs); expect(script.z).to.equal('A'); expect(script.y).to.equal(2); @@ -99,7 +99,7 @@ describe('adLoader', function () { it('should disable loading external script for activity rule set', function () { let unregisterRule; try { - unregisterRule = registerActivityControl(LOAD_EXTERNAL_SCRIPT, 'loadExternalScript config', () => ({allow: false})); + unregisterRule = registerActivityControl(LOAD_EXTERNAL_SCRIPT, 'loadExternalScript config', () => ({ allow: false })); adLoader.loadExternalScript(null, 'debugging'); expect(utilsLogErrorStub.called).to.be.false; } finally { diff --git a/test/spec/adserver_spec.js b/test/spec/adserver_spec.js index 50fefaaaa13..b967af32691 100644 --- a/test/spec/adserver_spec.js +++ b/test/spec/adserver_spec.js @@ -19,7 +19,7 @@ describe('adserver', function() { try { expect(getPPID()).to.equal('hooked'); } finally { - getPPID.getHooks({hook: hookFn}).remove(); + getPPID.getHooks({ hook: hookFn }).remove(); } }); }); diff --git a/test/spec/aliasBidder_spec.js b/test/spec/aliasBidder_spec.js index 4ac830dae50..3657534d59e 100644 --- a/test/spec/aliasBidder_spec.js +++ b/test/spec/aliasBidder_spec.js @@ -1,5 +1,5 @@ import { pbjsTestOnly } from 'test/helpers/pbjs-test-only.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; describe('Publisher API _ Alias Bidder', function () { var assert = require('chai').assert; diff --git a/test/spec/api_spec.js b/test/spec/api_spec.js index 21f4999b85a..77a0c4d9309 100755 --- a/test/spec/api_spec.js +++ b/test/spec/api_spec.js @@ -1,7 +1,7 @@ var assert = require('chai').assert; var prebid = require('../../src/prebid.js'); -const {getGlobalVarName} = require('../../src/buildOptions.js'); -const {getGlobal} = require('../../src/prebidGlobal.js'); +const { getGlobalVarName } = require('../../src/buildOptions.js'); +const { getGlobal } = require('../../src/prebidGlobal.js'); describe('Publisher API', function () { // var assert = chai.assert; diff --git a/test/spec/appnexusKeywords_spec.js b/test/spec/appnexusKeywords_spec.js index 53ffa87dd1a..635dc02f19e 100644 --- a/test/spec/appnexusKeywords_spec.js +++ b/test/spec/appnexusKeywords_spec.js @@ -1,5 +1,5 @@ -import {transformBidderParamKeywords} from '../../libraries/appnexusUtils/anKeywords.js'; -import {expect} from 'chai/index.js'; +import { transformBidderParamKeywords } from '../../libraries/appnexusUtils/anKeywords.js'; +import { expect } from 'chai/index.js'; import * as utils from '../../src/utils.js'; describe('transformBidderParamKeywords', function () { diff --git a/test/spec/auctionmanager_spec.js b/test/spec/auctionmanager_spec.js index 6ebb8666096..388ea2c5e2d 100644 --- a/test/spec/auctionmanager_spec.js +++ b/test/spec/auctionmanager_spec.js @@ -12,24 +12,24 @@ import * as auctionModule from 'src/auction.js'; import { registerBidder } from 'src/adapters/bidderFactory.js'; import { createBid } from 'src/bidfactory.js'; import { config } from 'src/config.js'; -import {_internal as store} from 'src/videoCache.js'; +import { _internal as store } from 'src/videoCache.js'; import * as ajaxLib from 'src/ajax.js'; import { server } from 'test/mocks/xhr.js'; -import {hook} from '../../src/hook.js'; -import {auctionManager} from '../../src/auctionManager.js'; +import { hook } from '../../src/hook.js'; +import { auctionManager } from '../../src/auctionManager.js'; import 'modules/debugging/index.js' // some tests look for debugging side effects -import {AuctionIndex} from '../../src/auctionIndex.js'; -import {expect} from 'chai'; -import {deepClone} from '../../src/utils.js'; +import { AuctionIndex } from '../../src/auctionIndex.js'; +import { expect } from 'chai'; +import { deepClone } from '../../src/utils.js'; import { IMAGE as ortbNativeRequest } from 'src/native.js'; -import {PrebidServer} from '../../modules/prebidServerBidAdapter/index.js'; +import { PrebidServer } from '../../modules/prebidServerBidAdapter/index.js'; import { setConfig as setCurrencyConfig } from '../../modules/currency.js' import { REJECTION_REASON } from '../../src/constants.js'; import { setDocumentHidden } from './unit/utils/focusTimeout_spec.js'; -import {sandbox} from 'sinon'; -import {getMinBidCacheTTL, onMinBidCacheTTLChange} from '../../src/bidTTL.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; +import { sandbox } from 'sinon'; +import { getMinBidCacheTTL, onMinBidCacheTTLChange } from '../../src/bidTTL.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; /** * @typedef {import('../src/adapters/bidderFactory.js').BidRequest} BidRequest @@ -149,7 +149,7 @@ function mockBidder(bidderCode, bids) { getUserSyncs: sinon.stub() }; - spec.buildRequests.returns([{'id': 123, 'method': 'POST'}]); + spec.buildRequests.returns([{ 'id': 123, 'method': 'POST' }]); spec.isBidRequestValid.returns(true); spec.interpretResponse.returns(bids); @@ -806,7 +806,7 @@ describe('auctionmanager.js', function () { code: ADUNIT_CODE, adUnitId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE}, + { bidder: BIDDER_CODE }, ] }]; }); @@ -822,7 +822,7 @@ describe('auctionmanager.js', function () { global: {}, bidder: {} } - const auction = auctionManager.createAuction({adUnits, ortb2Fragments}); + const auction = auctionManager.createAuction({ adUnits, ortb2Fragments }); auction.callBids(); const anyArgs = [...Array(7).keys()].map(() => sinon.match.any); sinon.assert.calledWith(stubMakeBidRequests, ...anyArgs.slice(0, 5).concat([sinon.match.same(ortb2Fragments)])); @@ -834,7 +834,7 @@ describe('auctionmanager.js', function () { global: {}, bidder: {} } - const auction = auctionManager.createAuction({adUnits, ortb2Fragments}); + const auction = auctionManager.createAuction({ adUnits, ortb2Fragments }); expect(auction.getNonBids()[0]).to.equal(undefined); events.emit(EVENTS.SEAT_NON_BID, { auctionId: auction.getAuctionId(), @@ -844,7 +844,7 @@ describe('auctionmanager.js', function () { }); it('resolves .requestsDone', async () => { - const auction = auctionManager.createAuction({adUnits}); + const auction = auctionManager.createAuction({ adUnits }); stubCallAdapters.resetHistory(); auction.callBids(); await auction.requestsDone; @@ -853,15 +853,15 @@ describe('auctionmanager.js', function () { describe('setConfig(minBidCacheTTL)', () => { it('should update getMinBidCacheTTL', () => { expect(getMinBidCacheTTL()).to.eql(null); - config.setConfig({minBidCacheTTL: 123}); + config.setConfig({ minBidCacheTTL: 123 }); expect(getMinBidCacheTTL()).to.eql(123); }); it('should run listeners registered with onMinBidCacheTTLChange', () => { - config.setConfig({minBidCacheTTL: 1}); + config.setConfig({ minBidCacheTTL: 1 }); let newTTL = null; onMinBidCacheTTLChange((ttl) => { newTTL = ttl; }); - config.setConfig({minBidCacheTTL: 2}); + config.setConfig({ minBidCacheTTL: 2 }); expect(newTTL).to.eql(2); }) }) @@ -870,7 +870,7 @@ describe('auctionmanager.js', function () { let clock, auction; beforeEach(() => { clock = sinon.useFakeTimers(); - auction = auctionManager.createAuction({adUnits}); + auction = auctionManager.createAuction({ adUnits }); indexAuctions.push(auction); }); afterEach(() => { @@ -991,7 +991,7 @@ describe('auctionmanager.js', function () { bd: [], entries: () => auctionManager.getNoBids() } - }).forEach(([t, {bd, entries}]) => { + }).forEach(([t, { bd, entries }]) => { it(`with ${t} are never dropped if minBidCacheTTL is not set`, () => { bids = bd; auction.callBids(); @@ -1036,13 +1036,13 @@ describe('auctionmanager.js', function () { code: ADUNIT_CODE, adUnitId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE, params: { placementId: 'id' } }, ] }]; adUnitCodes = [ADUNIT_CODE]; - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); + auction = auctionModule.newAuction({ adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000 }); bids = TEST_BIDS.slice(); - bidderRequests = bids.map(b => mockBidRequest(b, {auctionId: auction.getAuctionId()})); + bidderRequests = bids.map(b => mockBidRequest(b, { auctionId: auction.getAuctionId() })); makeRequestsStub.returns(bidderRequests); indexAuctions = [auction]; createAuctionStub = sinon.stub(auctionModule, 'newAuction'); @@ -1130,7 +1130,7 @@ describe('auctionmanager.js', function () { mediaType: 'banner', } ); - Object.assign(getObj(), {renderer}); + Object.assign(getObj(), { renderer }); spec.interpretResponse.returns(bid); auction.callBids(); return auction.getBidsReceived().pop(); @@ -1153,7 +1153,7 @@ describe('auctionmanager.js', function () { backupOnly: true, render: (bid) => bid }; - Object.assign(adUnits[0], {renderer}); + Object.assign(adUnits[0], { renderer }); const bids1 = Object.assign({}, bids[0], @@ -1236,11 +1236,11 @@ describe('auctionmanager.js', function () { url: 'renderer.js', render: (bid) => bid }; - Object.assign(adUnits[0], {renderer}); + Object.assign(adUnits[0], { renderer }); // make sure that if the renderer is only on the second ad unit, prebid // still correctly uses it const bid = mockBid(); - const bidRequests = [mockBidRequest(bid, {auctionId: auction.getAuctionId()})]; + const bidRequests = [mockBidRequest(bid, { auctionId: auction.getAuctionId() })]; bidRequests[0].bids[1] = Object.assign({ bidId: utils.getUniqueIdentifierStr() @@ -1295,9 +1295,9 @@ describe('auctionmanager.js', function () { request: undefined, response: false } - ].forEach(({request, response}) => { + ].forEach(({ request, response }) => { it(`sets bidResponse.instl to ${response} if adUnit.ortb2Imp.instl is ${request}`, () => { - adUnits[0].ortb2Imp = {instl: request}; + adUnits[0].ortb2Imp = { instl: request }; auction.callBids(); expect(auction.getBidsReceived()[0].instl).to.equal(response); }) @@ -1312,7 +1312,7 @@ describe('auctionmanager.js', function () { } function runAuction() { - const bidRequests = bids.map(bid => mockBidRequest(bid, {auctionId: auction.getAuctionId()})); + const bidRequests = bids.map(bid => mockBidRequest(bid, { auctionId: auction.getAuctionId() })); makeRequestsStub.returns(bidRequests); return new Promise((resolve) => { auctionDone = resolve; @@ -1326,8 +1326,8 @@ describe('auctionmanager.js', function () { transactionId: ADUNIT_CODE, adUnitId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, - {bidder: BIDDER_CODE1, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE, params: { placementId: 'id' } }, + { bidder: BIDDER_CODE1, params: { placementId: 'id' } }, ] }]; adUnitCodes = [ADUNIT_CODE]; @@ -1338,7 +1338,7 @@ describe('auctionmanager.js', function () { registerBidder(spec1); const spec2 = mockBidder(BIDDER_CODE1, [bids[1]]); registerBidder(spec2); - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: () => auctionDone(), cbTimeout: 20}); + auction = auctionModule.newAuction({ adUnits, adUnitCodes, callback: () => auctionDone(), cbTimeout: 20 }); indexAuctions = [auction]; }); @@ -1375,7 +1375,7 @@ describe('auctionmanager.js', function () { it(t, () => { const pm = runAuction().then(() => { if (shouldFire) { - sinon.assert.calledWith(handler, sinon.match({auctionId: auction.getAuctionId()})) + sinon.assert.calledWith(handler, sinon.match({ auctionId: auction.getAuctionId() })) } else { sinon.assert.notCalled(handler); } @@ -1460,7 +1460,7 @@ describe('auctionmanager.js', function () { }, }] }) - adUnits[0].bids.push({bidder: 'mock-s2s-1'}, {bidder: 'mock-s2s-2'}) + adUnits[0].bids.push({ bidder: 'mock-s2s-1' }, { bidder: 'mock-s2s-2' }) const s2sAdUnits = deepClone(adUnits); bids.unshift( mockBid({ bidderCode: 'mock-s2s-1', src: S2S.SRC, adUnits: s2sAdUnits, uniquePbsTid: '1' }), @@ -1516,18 +1516,18 @@ describe('auctionmanager.js', function () { transactionId: ADUNIT_CODE, adUnitId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE, params: { placementId: 'id' } }, ] }, { code: ADUNIT_CODE1, transactionId: ADUNIT_CODE1, adUnitId: ADUNIT_CODE1, bids: [ - {bidder: BIDDER_CODE1, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE1, params: { placementId: 'id' } }, ] }]; adUnitCodes = adUnits.map(({ code }) => code); - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); + auction = auctionModule.newAuction({ adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000 }); const bidRequests = [ mockBidRequest(bids[0], { auctionId: auction.getAuctionId() }), mockBidRequest(bids1[0], { auctionId: auction.getAuctionId(), adUnitCode: ADUNIT_CODE1 }) @@ -1574,11 +1574,11 @@ describe('auctionmanager.js', function () { }); it('should run auction after video bids have been cached', async function () { - sinon.stub(store, 'store').callsArgWith(1, null, [{uuid: 123}]); + sinon.stub(store, 'store').callsArgWith(1, null, [{ uuid: 123 }]); sinon.stub(config, 'getConfig').withArgs('cache.url').returns('cache-url'); - const bidsCopy = [Object.assign({}, bids[0], {mediaType: 'video'})]; - const bids1Copy = [Object.assign({}, bids1[0], {mediaType: 'video'})]; + const bidsCopy = [Object.assign({}, bids[0], { mediaType: 'video' })]; + const bids1Copy = [Object.assign({}, bids1[0], { mediaType: 'video' })]; spec.interpretResponse.returns(bidsCopy); spec1.interpretResponse.returns(bids1Copy); @@ -1594,16 +1594,16 @@ describe('auctionmanager.js', function () { }); it('runs auction after video responses with multiple bid objects have been cached', async function () { - sinon.stub(store, 'store').callsArgWith(1, null, [{uuid: 123}]); + sinon.stub(store, 'store').callsArgWith(1, null, [{ uuid: 123 }]); sinon.stub(config, 'getConfig').withArgs('cache.url').returns('cache-url'); const bidsCopy = [ - Object.assign({}, bids[0], {mediaType: 'video'}), - Object.assign({}, bids[0], {mediaType: 'banner'}), + Object.assign({}, bids[0], { mediaType: 'video' }), + Object.assign({}, bids[0], { mediaType: 'banner' }), ]; const bids1Copy = [ - Object.assign({}, bids1[0], {mediaType: 'video'}), - Object.assign({}, bids1[0], {mediaType: 'video'}), + Object.assign({}, bids1[0], { mediaType: 'video' }), + Object.assign({}, bids1[0], { mediaType: 'video' }), ]; spec.interpretResponse.returns(bidsCopy); @@ -1626,7 +1626,7 @@ describe('auctionmanager.js', function () { }); auction.callBids(); - sinon.assert.calledWith(auction.addBidRejected, sinon.match({rejectionReason: REJECTION_REASON.PRICE_TOO_HIGH})); + sinon.assert.calledWith(auction.addBidRejected, sinon.match({ rejectionReason: REJECTION_REASON.PRICE_TOO_HIGH })); }) }); @@ -1675,17 +1675,17 @@ describe('auctionmanager.js', function () { code: ADUNIT_CODE, transactionId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE, params: { placementId: 'id' } }, ] }, { code: ADUNIT_CODE1, transactionId: ADUNIT_CODE1, bids: [ - {bidder: BIDDER_CODE1, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE1, params: { placementId: 'id' } }, ] }]; adUnitCodes = adUnits.map(({ code }) => code); - auction = auctionModule.newAuction({adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000}); + auction = auctionModule.newAuction({ adUnits, adUnitCodes, callback: function() {}, cbTimeout: 3000 }); createAuctionStub = sinon.stub(auctionModule, 'newAuction'); createAuctionStub.returns(auction); indexAuctions = [auction]; @@ -1743,12 +1743,12 @@ describe('auctionmanager.js', function () { transactionId: ADUNIT_CODE, adUnitId: ADUNIT_CODE, bids: [ - {bidder: BIDDER_CODE, params: {placementId: 'id'}}, + { bidder: BIDDER_CODE, params: { placementId: 'id' } }, ], nativeOrtbRequest: ortbNativeRequest.ortb, mediaTypes: { native: { type: 'image' } } }]; - auction = auctionModule.newAuction({adUnits, adUnitCodes: [ADUNIT_CODE], callback: function() {}, cbTimeout: 3000}); + auction = auctionModule.newAuction({ adUnits, adUnitCodes: [ADUNIT_CODE], callback: function() {}, cbTimeout: 3000 }); indexAuctions = [auction]; const createAuctionStub = sinon.stub(auctionModule, 'newAuction'); createAuctionStub.returns(auction); @@ -1806,7 +1806,7 @@ describe('auctionmanager.js', function () { describe('getMediaTypeGranularity', function () { if (FEATURES.VIDEO) { it('video', function () { - let mediaTypes = { video: {id: '1'} }; + let mediaTypes = { video: { id: '1' } }; // mediaType is video and video.context is undefined expect(getMediaTypeGranularity('video', mediaTypes, { @@ -1857,14 +1857,14 @@ describe('auctionmanager.js', function () { banner: 'low', video: 'medium' })).to.equal('medium'); - expect(getMediaTypeGranularity('video', {mediaTypes: {banner: {}}}, { + expect(getMediaTypeGranularity('video', { mediaTypes: { banner: {} } }, { banner: 'low', video: 'medium' })).to.equal('medium'); }); } it('native', function () { - expect(getMediaTypeGranularity('native', {native: {}}, { + expect(getMediaTypeGranularity('native', { native: {} }, { banner: 'low', video: 'medium', native: 'high' })).to.equal('high'); }); @@ -1876,8 +1876,8 @@ describe('auctionmanager.js', function () { sandbox = sinon.createSandbox(); sandbox.stub(adapterManager, 'callBidWonBidder'); sandbox.stub(adapterManager, 'triggerBilling') - adUnits = [{code: 'au1'}, {code: 'au2'}] - auction = newAuction({adUnits}); + adUnits = [{ code: 'au1' }, { code: 'au2' }] + auction = newAuction({ adUnits }); bid = { bidder: 'mock-bidder' }; @@ -1937,13 +1937,13 @@ describe('auctionmanager.js', function () { expect(gpbg({ mediaType: 'video', pbMg: 'medium' }, { - 'mediaTypes': {video: {id: '1'}} + 'mediaTypes': { video: { id: '1' } } })).to.equal('medium'); expect(gpbg({ mediaType: 'banner', pbLg: 'low' }, { - 'mediaTypes': {banner: {}} + 'mediaTypes': { banner: {} } })).to.equal('low'); }); }) @@ -1958,7 +1958,7 @@ describe('auctionmanager.js', function () { responsesReady.before(responsesReadyHook, 100); }); after(() => { - responsesReady.getHooks({hook: responsesReadyHook}).remove(); + responsesReady.getHooks({ hook: responsesReadyHook }).remove(); }); beforeEach(() => { @@ -1998,12 +1998,12 @@ describe('auctionmanager.js', function () { const ADUNIT_CODE2 = 'adUnitCode2'; const BIDDER_CODE2 = 'sampleBidder2'; - const bids1 = [mockBid({bidderCode: BIDDER_CODE1, adUnitId: ADUNIT_CODE1})]; - const bids2 = [mockBid({bidderCode: BIDDER_CODE2, adUnitId: ADUNIT_CODE2})]; + const bids1 = [mockBid({ bidderCode: BIDDER_CODE1, adUnitId: ADUNIT_CODE1 })]; + const bids2 = [mockBid({ bidderCode: BIDDER_CODE2, adUnitId: ADUNIT_CODE2 })]; bidRequests = [ mockBidRequest(bids[0]), - mockBidRequest(bids1[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids2[0], {adUnitCode: ADUNIT_CODE2}) + mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE2 }) ]; const cbs = auctionCallbacks(doneSpy, auction); const method = getMethod(cbs); @@ -2021,7 +2021,7 @@ describe('auctionmanager.js', function () { if (FEATURES.VIDEO) { it('should call auction done after prebid cache is complete for mediaType video', async function () { bids[0].mediaType = 'video'; - const bids1 = [mockBid({bidderCode: BIDDER_CODE1})]; + const bids1 = [mockBid({ bidderCode: BIDDER_CODE1 })]; const opts = { mediaType: { @@ -2033,7 +2033,7 @@ describe('auctionmanager.js', function () { }; bidRequests = [ mockBidRequest(bids[0], opts), - mockBidRequest(bids1[0], {adUnitCode: ADUNIT_CODE1}), + mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), ]; const cbs = auctionCallbacks(doneSpy, auction); @@ -2045,7 +2045,7 @@ describe('auctionmanager.js', function () { assert.equal(doneSpy.callCount, 0); const uuid = 'c488b101-af3e-4a99-b538-00423e5a3371'; const responseBody = `{"responses":[{"uuid":"${uuid}"}]}`; - server.requests[0].respond(200, {'Content-Type': 'application/json'}, responseBody); + server.requests[0].respond(200, { 'Content-Type': 'application/json' }, responseBody); assert.equal(doneSpy.callCount, 1); }); } @@ -2053,10 +2053,10 @@ describe('auctionmanager.js', function () { it('should convert cpm to number', () => { auction.addBidReceived = sinon.spy(); const cbs = auctionCallbacks(doneSpy, auction); - const bid = {...bids[0], cpm: '1.23'} + const bid = { ...bids[0], cpm: '1.23' } bidRequests = [mockBidRequest(bid)]; cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE, bid); - sinon.assert.calledWith(auction.addBidReceived, sinon.match({cpm: 1.23})); + sinon.assert.calledWith(auction.addBidReceived, sinon.match({ cpm: 1.23 })); }) describe('when responsesReady defers', () => { @@ -2071,7 +2071,7 @@ describe('auctionmanager.js', function () { }); after(() => { - responsesReady.getHooks({hook}).remove(); + responsesReady.getHooks({ hook }).remove(); }); beforeEach(() => { @@ -2081,8 +2081,8 @@ describe('auctionmanager.js', function () { reject = rj; }); bids = [ - mockBid({bidderCode: BIDDER_CODE1}), - mockBid({bidderCode: BIDDER_CODE}) + mockBid({ bidderCode: BIDDER_CODE1 }), + mockBid({ bidderCode: BIDDER_CODE }) ] bidRequests = bids.map((b) => mockBidRequest(b)); callbacks = auctionCallbacks(doneSpy, auction); @@ -2126,13 +2126,13 @@ describe('auctionmanager.js', function () { }); after(() => { - addBidResponse.getHooks({hook: rejectHook}).remove(); + addBidResponse.getHooks({ hook: rejectHook }).remove(); events.off(EVENTS.BID_REJECTED, onBidRejected); }); beforeEach(() => { onBidRejected.resetHistory(); - bid = mockBid({bidderCode: BIDDER_CODE}); + bid = mockBid({ bidderCode: BIDDER_CODE }); bidRequests = [ mockBidRequest(bid), ]; @@ -2182,7 +2182,7 @@ describe('auctionmanager.js', function () { doneSpy = sinon.spy(); config.setConfig({ 'auctionOptions': { - secondaryBidders: [ secondaryBidder ] + secondaryBidders: [secondaryBidder] } }); @@ -2198,13 +2198,13 @@ describe('auctionmanager.js', function () { }); it('should not wait to call auction done for secondary bidders', async function () { - const bids1 = [mockBid({bidderCode: requiredBidder, transactionId: ADUNIT_CODE1})]; - const bids2 = [mockBid({bidderCode: requiredBidder1, transactionId: ADUNIT_CODE1})]; - const bids3 = [mockBid({bidderCode: secondaryBidder, transactionId: ADUNIT_CODE1})]; + const bids1 = [mockBid({ bidderCode: requiredBidder, transactionId: ADUNIT_CODE1 })]; + const bids2 = [mockBid({ bidderCode: requiredBidder1, transactionId: ADUNIT_CODE1 })]; + const bids3 = [mockBid({ bidderCode: secondaryBidder, transactionId: ADUNIT_CODE1 })]; bidRequests = [ - mockBidRequest(bids1[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids2[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids3[0], {adUnitCode: ADUNIT_CODE1}), + mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), ]; const cbs = auctionCallbacks(doneSpy, auction); // required bidder responds immeaditely to auction @@ -2231,13 +2231,13 @@ describe('auctionmanager.js', function () { secondaryBidders: [requiredBidder, requiredBidder1, secondaryBidder] } }) - const bids1 = [mockBid({bidderCode: requiredBidder})]; - const bids2 = [mockBid({bidderCode: requiredBidder1})]; - const bids3 = [mockBid({bidderCode: secondaryBidder})]; + const bids1 = [mockBid({ bidderCode: requiredBidder })]; + const bids2 = [mockBid({ bidderCode: requiredBidder1 })]; + const bids3 = [mockBid({ bidderCode: secondaryBidder })]; bidRequests = [ - mockBidRequest(bids1[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids2[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids3[0], {adUnitCode: ADUNIT_CODE1}), + mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), ]; const cbs = auctionCallbacks(doneSpy, auction); cbs.addBidResponse.call(bidRequests[0], ADUNIT_CODE1, bids1[0]); @@ -2259,13 +2259,13 @@ describe('auctionmanager.js', function () { }); it('should allow secondaryBidders to respond in auction before is is done', async function () { - const bids1 = [mockBid({bidderCode: requiredBidder})]; - const bids2 = [mockBid({bidderCode: requiredBidder1})]; - const bids3 = [mockBid({bidderCode: secondaryBidder})]; + const bids1 = [mockBid({ bidderCode: requiredBidder })]; + const bids2 = [mockBid({ bidderCode: requiredBidder1 })]; + const bids3 = [mockBid({ bidderCode: secondaryBidder })]; bidRequests = [ - mockBidRequest(bids1[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids2[0], {adUnitCode: ADUNIT_CODE1}), - mockBidRequest(bids3[0], {adUnitCode: ADUNIT_CODE1}), + mockBidRequest(bids1[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids2[0], { adUnitCode: ADUNIT_CODE1 }), + mockBidRequest(bids3[0], { adUnitCode: ADUNIT_CODE1 }), ]; const cbs = auctionCallbacks(doneSpy, auction); // secondaryBidder is first to respond diff --git a/test/spec/banner_spec.js b/test/spec/banner_spec.js index f60f2023194..daf6aeecf77 100644 --- a/test/spec/banner_spec.js +++ b/test/spec/banner_spec.js @@ -23,7 +23,7 @@ describe('banner', () => { otherOne: 'test' }; - const expected = {...mt}; + const expected = { ...mt }; delete expected.api; const adUnit = { @@ -80,7 +80,7 @@ describe('banner', () => { const adUnit = { mediaTypes: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [1, 2, 34], // should be overwritten with value from ortb2Imp battr: [3, 4], maxduration: 'omitted_value' // should be omitted during copying - not part of banner obj spec @@ -100,7 +100,7 @@ describe('banner', () => { const expected = { mediaTypes: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -110,7 +110,7 @@ describe('banner', () => { }, ortb2Imp: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], request: '{payload: true}', pos: 5, btype: [999, 999], @@ -131,12 +131,12 @@ describe('banner', () => { const adUnit = { mediaTypes: { banner: { - format: [{wratio: 1, hratio: 1}] + format: [{ wratio: 1, hratio: 1 }] } }, ortb2Imp: { banner: { - format: [{wratio: 1, hratio: 1}] + format: [{ wratio: 1, hratio: 1 }] } } } @@ -168,7 +168,7 @@ describe('banner', () => { const adUnit = { mediaTypes: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -181,7 +181,7 @@ describe('banner', () => { const expected1 = { mediaTypes: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -191,7 +191,7 @@ describe('banner', () => { }, ortb2Imp: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -207,7 +207,7 @@ describe('banner', () => { mediaTypes: {}, ortb2Imp: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -220,7 +220,7 @@ describe('banner', () => { const expected2 = { mediaTypes: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], @@ -229,7 +229,7 @@ describe('banner', () => { }, ortb2Imp: { banner: { - format: [{w: 100, h: 100}], + format: [{ w: 100, h: 100 }], btype: [999, 999], pos: 5, battr: [3, 4], diff --git a/test/spec/config_spec.js b/test/spec/config_spec.js index 51ac5ca1291..b13e9a15967 100644 --- a/test/spec/config_spec.js +++ b/test/spec/config_spec.js @@ -46,7 +46,7 @@ describe('config API', function () { }); it('readConfig returns deepCopy of the internal config object', function () { - setConfig({ foo: {biz: 'bar'} }); + setConfig({ foo: { biz: 'bar' } }); const config1 = readConfig('foo'); config1.biz = 'buz'; const config2 = readConfig('foo'); @@ -108,16 +108,16 @@ describe('config API', function () { it('getConfig subscribers are called immediately if passed {init: true}', () => { const listener = sinon.spy(); - setConfig({foo: 'bar'}); - getConfig('foo', listener, {init: true}); - sinon.assert.calledWith(listener, {foo: 'bar'}); + setConfig({ foo: 'bar' }); + getConfig('foo', listener, { init: true }); + sinon.assert.calledWith(listener, { foo: 'bar' }); }); it('getConfig subscribers with no topic are called immediately if passed {init: true}', () => { const listener = sinon.spy(); - setConfig({foo: 'bar'}); - getConfig(listener, {init: true}); - sinon.assert.calledWith(listener, sinon.match({foo: 'bar'})); + setConfig({ foo: 'bar' }); + getConfig(listener, { init: true }); + sinon.assert.calledWith(listener, sinon.match({ foo: 'bar' })); }); it('sets and gets arbitrary configuration properties', function () { @@ -139,9 +139,9 @@ describe('config API', function () { }); it('overwrites existing config properties', function () { - setConfig({ foo: {biz: 'buz'} }); - setConfig({ foo: {baz: 'qux'} }); - expect(getConfig('foo')).to.eql({baz: 'qux'}); + setConfig({ foo: { biz: 'buz' } }); + setConfig({ foo: { baz: 'qux' } }); + expect(getConfig('foo')).to.eql({ baz: 'qux' }); }); it('sets debugging', function () { @@ -167,7 +167,7 @@ describe('config API', function () { syncDelay: 3000, auctionDelay: 0 }; - setDefaults({'userSync': DEFAULT_USERSYNC}); + setDefaults({ 'userSync': DEFAULT_USERSYNC }); expect(getConfig('userSync')).to.eql(DEFAULT_USERSYNC); }); @@ -258,10 +258,10 @@ describe('config API', function () { getter: () => config.getConfig }, 'using setBidderConfig': { - setter: () => (config) => setBidderConfig({bidders: ['mockBidder'], config}), + setter: () => (config) => setBidderConfig({ bidders: ['mockBidder'], config }), getter: () => (option) => config.runWithBidder('mockBidder', () => config.getConfig(option)) } - }).forEach(([t, {getter, setter}]) => { + }).forEach(([t, { getter, setter }]) => { describe(t, () => { let getConfig, setConfig; beforeEach(() => { @@ -284,8 +284,8 @@ describe('config API', function () { }); it('does not force defaults for bidder config', () => { - config.setConfig({bidderSequence: 'fixed'}); - config.setBidderConfig({bidders: ['mockBidder'], config: {other: 'config'}}) + config.setConfig({ bidderSequence: 'fixed' }); + config.setBidderConfig({ bidders: ['mockBidder'], config: { other: 'config' } }) expect(config.runWithBidder('mockBidder', () => config.getConfig('bidderSequence'))).to.eql('fixed'); }) @@ -361,36 +361,44 @@ describe('config API', function () { }); it('should log warning for invalid auctionOptions bidder values', function () { - setConfig({ auctionOptions: { - 'secondaryBidders': 'appnexus, rubicon', - }}); + setConfig({ + auctionOptions: { + 'secondaryBidders': 'appnexus, rubicon', + } + }); expect(logWarnSpy.calledOnce).to.equal(true); const warning = 'Auction Options secondaryBidders must be of type Array'; assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged'); }); it('should log warning for invalid auctionOptions suppress stale render', function () { - setConfig({ auctionOptions: { - 'suppressStaleRender': 'test', - }}); + setConfig({ + auctionOptions: { + 'suppressStaleRender': 'test', + } + }); expect(logWarnSpy.calledOnce).to.equal(true); const warning = 'Auction Options suppressStaleRender must be of type boolean'; assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged'); }); it('should log warning for invalid auctionOptions suppress expired render', function () { - setConfig({ auctionOptions: { - 'suppressExpiredRender': 'test', - }}); + setConfig({ + auctionOptions: { + 'suppressExpiredRender': 'test', + } + }); expect(logWarnSpy.calledOnce).to.equal(true); const warning = 'Auction Options suppressExpiredRender must be of type boolean'; assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged'); }); it('should log warning for invalid properties to auctionOptions', function () { - setConfig({ auctionOptions: { - 'testing': true - }}); + setConfig({ + auctionOptions: { + 'testing': true + } + }); expect(logWarnSpy.calledOnce).to.equal(true); const warning = 'Auction Options given an incorrect param: testing'; assert.ok(logWarnSpy.calledWith(warning), 'expected warning was logged'); @@ -408,16 +416,17 @@ describe('config API', function () { } } }; - setConfig({ ortb2: { - user: { - ext: { - data: { - registered: true, - interests: ['cars'] + setConfig({ + ortb2: { + user: { + ext: { + data: { + registered: true, + interests: ['cars'] + } } } } - } }); mergeConfig(obj); const expected = { @@ -453,15 +462,17 @@ describe('config API', function () { } } } - setConfig({ ortb2: { - user: { - ext: { - data: { - registered: false + setConfig({ + ortb2: { + user: { + ext: { + data: { + registered: false + } } } } - }}); + }); mergeConfig(input); const expected = { user: { diff --git a/test/spec/creative/crossDomainCreative_spec.js b/test/spec/creative/crossDomainCreative_spec.js index ac63bcf8f79..41dfd391569 100644 --- a/test/spec/creative/crossDomainCreative_spec.js +++ b/test/spec/creative/crossDomainCreative_spec.js @@ -1,4 +1,4 @@ -import {renderer} from '../../../creative/crossDomain.js'; +import { renderer } from '../../../creative/crossDomain.js'; import { ERROR_EXCEPTION, EVENT_AD_RENDER_FAILED, EVENT_AD_RENDER_SUCCEEDED, @@ -38,9 +38,9 @@ describe('cross-domain creative', () => { }, parent: { parent: top, - frames: {'__pb_locator__': {}}, + frames: { '__pb_locator__': {} }, postMessage: sinon.stub().callsFake((payload, targetOrigin, transfer) => { - messages.push({payload: JSON.parse(payload), targetOrigin, transfer}); + messages.push({ payload: JSON.parse(payload), targetOrigin, transfer }); }) } }; @@ -73,7 +73,7 @@ describe('cross-domain creative', () => { } it('derives postMessage target origin from pubUrl ', () => { - renderAd({pubUrl: 'https://domain.com:123/path'}); + renderAd({ pubUrl: 'https://domain.com:123/path' }); expect(messages[0].targetOrigin).to.eql('https://domain.com:123') }); @@ -88,7 +88,7 @@ describe('cross-domain creative', () => { ...target, parent: { top, - frames: {'__pb_locator__': {}}, + frames: { '__pb_locator__': {} }, parent: { top, frames: {} @@ -103,10 +103,10 @@ describe('cross-domain creative', () => { }).forEach(([t, getFrames]) => { describe(`when an ancestor ${t}`, () => { beforeEach(() => { - Object.defineProperty(win.parent.parent.parent.parent, 'frames', {get: getFrames}) + Object.defineProperty(win.parent.parent.parent.parent, 'frames', { get: getFrames }) }) it('posts message to the first ancestor with __pb_locator__ child', () => { - renderAd({pubUrl: 'https://www.example.com'}); + renderAd({ pubUrl: 'https://www.example.com' }); expect(messages.length).to.eql(1); }); }) @@ -117,13 +117,13 @@ describe('cross-domain creative', () => { throw new DOMException(); } }); - renderAd({pubUrl: 'https://www.example.com'}); + renderAd({ pubUrl: 'https://www.example.com' }); expect(messages.length).to.eql(1); }) }) it('generates request message with adId and clickUrl', () => { - renderAd({adId: '123', clickUrl: 'https://click-url.com', pubUrl: ORIGIN}); + renderAd({ adId: '123', clickUrl: 'https://click-url.com', pubUrl: ORIGIN }); expect(messages[0].payload).to.eql({ message: MESSAGE_REQUEST, adId: '123', @@ -149,15 +149,15 @@ describe('cross-domain creative', () => { } it('ignores messages that are not a prebid response message', () => { - renderAd({adId: '123', pubUrl: ORIGIN}); - reply({adId: '123', ad: 'markup'}); + renderAd({ adId: '123', pubUrl: ORIGIN }); + reply({ adId: '123', ad: 'markup' }); sinon.assert.notCalled(mkIframe); }) it('signals AD_RENDER_FAILED on exceptions', () => { mkIframe.callsFake(() => { throw new Error('error message') }); - renderAd({adId: '123', pubUrl: ORIGIN}); - reply({message: MESSAGE_RESPONSE, adId: '123', ad: 'markup'}); + renderAd({ adId: '123', pubUrl: ORIGIN }); + reply({ message: MESSAGE_RESPONSE, adId: '123', ad: 'markup' }); return waitFor(() => messages[1]?.payload).then(() => { expect(messages[1].payload).to.eql({ message: MESSAGE_EVENT, @@ -184,7 +184,7 @@ describe('cross-domain creative', () => { adId: '123', renderer: 'window.render = window.parent._render' } - renderAd({adId: '123', pubUrl: ORIGIN}); + renderAd({ adId: '123', pubUrl: ORIGIN }); reply(data); return waitFor(() => window._render.args.length).then(() => { sinon.assert.calledWith(window._render, data, sinon.match.any, win); @@ -201,7 +201,7 @@ describe('cross-domain creative', () => { 'rejects (w/reason)': ['window.render = function() { return Promise.reject({reason: "other", message: "msg"}) }', 'other'], }).forEach(([t, [renderer, reason = ERROR_EXCEPTION, message = 'msg']]) => { it(`signals AD_RENDER_FAILED on renderer that ${t}`, () => { - renderAd({adId: '123', pubUrl: ORIGIN}); + renderAd({ adId: '123', pubUrl: ORIGIN }); reply({ message: MESSAGE_RESPONSE, adId: '123', @@ -222,7 +222,7 @@ describe('cross-domain creative', () => { }); it('signals AD_RENDER_SUCCEEDED when renderer resolves', () => { - renderAd({adId: '123', pubUrl: ORIGIN}); + renderAd({ adId: '123', pubUrl: ORIGIN }); reply({ message: MESSAGE_RESPONSE, adId: '123', @@ -244,7 +244,7 @@ describe('cross-domain creative', () => { }) it('is provided a sendMessage that accepts replies', () => { - renderAd({adId: '123', pubUrl: ORIGIN}); + renderAd({ adId: '123', pubUrl: ORIGIN }); window._reply = sinon.stub(); reply({ adId: '123', @@ -255,7 +255,7 @@ describe('cross-domain creative', () => { reply('response', 1); return waitFor(() => window._reply.args.length) }).then(() => { - sinon.assert.calledWith(window._reply, sinon.match({data: JSON.stringify('response')})); + sinon.assert.calledWith(window._reply, sinon.match({ data: JSON.stringify('response') })); }).finally(() => { delete window._reply; }) diff --git a/test/spec/creative/displayRenderer_spec.js b/test/spec/creative/displayRenderer_spec.js index a269d5f4e33..95bc0ebab9e 100644 --- a/test/spec/creative/displayRenderer_spec.js +++ b/test/spec/creative/displayRenderer_spec.js @@ -1,10 +1,10 @@ -import {render} from 'creative/renderers/display/renderer.js'; -import {ERROR_NO_AD} from '../../../creative/renderers/display/constants.js'; +import { render } from 'creative/renderers/display/renderer.js'; +import { ERROR_NO_AD } from '../../../creative/renderers/display/constants.js'; describe('Creative renderer - display', () => { let doc, mkFrame, sendMessage, win; beforeEach(() => { - mkFrame = sinon.stub().callsFake((doc, attrs) => Object.assign({doc}, attrs)); + mkFrame = sinon.stub().callsFake((doc, attrs) => Object.assign({ doc }, attrs)); sendMessage = sinon.stub(); doc = { body: { @@ -17,7 +17,7 @@ describe('Creative renderer - display', () => { }); function runRenderer(data) { - return render(data, {sendMessage, mkFrame}, win); + return render(data, { sendMessage, mkFrame }, win); } it('throws when both ad and adUrl are missing', () => { @@ -57,7 +57,7 @@ describe('Creative renderer - display', () => { }) it('defaults width and height to 100%', () => { - runRenderer({ad: 'mock'}); + runRenderer({ ad: 'mock' }); sinon.assert.calledWith(doc.body.appendChild, sinon.match({ doc, width: '100%', @@ -72,13 +72,13 @@ describe('Creative renderer - display', () => { style: {} } }) - runRenderer({ad: 'mock'}); + runRenderer({ ad: 'mock' }); expect(doc.body.style.height).to.eql('100%'); expect(doc.body.parentElement.style.height).to.eql('100%'); }); it('sizes frame element if instl = true', () => { - win.frameElement = { style: {}}; + win.frameElement = { style: {} }; runRenderer({ ad: 'mock', width: 123, diff --git a/test/spec/creative/nativeRenderer_spec.js b/test/spec/creative/nativeRenderer_spec.js index 02971088a1e..6c149bec7af 100644 --- a/test/spec/creative/nativeRenderer_spec.js +++ b/test/spec/creative/nativeRenderer_spec.js @@ -1,5 +1,5 @@ -import {getAdMarkup, getReplacements, getReplacer} from '../../../creative/renderers/native/renderer.js'; -import {ACTION_CLICK, ACTION_IMP, ACTION_RESIZE, MESSAGE_NATIVE} from '../../../creative/renderers/native/constants.js'; +import { getAdMarkup, getReplacements, getReplacer } from '../../../creative/renderers/native/renderer.js'; +import { ACTION_CLICK, ACTION_IMP, ACTION_RESIZE, MESSAGE_NATIVE } from '../../../creative/renderers/native/constants.js'; describe('Native creative renderer', () => { let win; @@ -45,7 +45,7 @@ describe('Native creative renderer', () => { document.body.removeChild(frame); }) it('with adTemplate, if present', () => { - return getAdMarkup('123', {adTemplate: 'tpl'}, replacer, win).then((result) => { + return getAdMarkup('123', { adTemplate: 'tpl' }, replacer, win).then((result) => { expect(result).to.eql('markup'); sinon.assert.calledWith(replacer, 'tpl'); }); @@ -83,8 +83,8 @@ describe('Native creative renderer', () => { ortb: { assets: [{ id: 1, - link: {url: 'l1'}, - data: {value: 'v1'} + link: { url: 'l1' }, + data: { value: 'v1' } }] } }); @@ -99,7 +99,7 @@ describe('Native creative renderer', () => { it('replaces placeholders for for legacy assets', () => { const repl = getReplacer('123', { assets: [ - {key: 'k1', value: 'v1'}, {key: 'k2', value: 'v2'} + { key: 'k1', value: 'v1' }, { key: 'k2', value: 'v2' } ], nativeKeys: { k1: 'hb_native_k1', @@ -135,8 +135,8 @@ describe('Native creative renderer', () => { const repl = getReplacer('123', { ortb, assets: [ - {key: 'clickUrl', value: 'overridden'}, - {key: 'privacyLink', value: 'overridden'} + { key: 'clickUrl', value: 'overridden' }, + { key: 'privacyLink', value: 'overridden' } ], nativeKeys: { clickUrl: 'hb_native_linkurl', @@ -157,10 +157,10 @@ describe('Native creative renderer', () => { }); Object.entries({ - title: {text: 'val'}, - data: {value: 'val'}, - img: {url: 'val'}, - video: {vasttag: 'val'} + title: { text: 'val' }, + data: { value: 'val' }, + img: { url: 'val' }, + video: { vasttag: 'val' } }).forEach(([type, contents]) => { describe(`for ortb ${type} asset`, () => { let ortb; @@ -175,14 +175,14 @@ describe('Native creative renderer', () => { }; }); it('replaces placeholder', () => { - const repl = getReplacer('', {ortb}); + const repl = getReplacer('', { ortb }); expectReplacements(repl, { '##hb_native_asset_id_123##': 'val' }) }); it('replaces link placeholders', () => { - ortb.assets[0].link = {url: 'link'}; - const repl = getReplacer('', {ortb}); + ortb.assets[0].link = { url: 'link' }; + const repl = getReplacer('', { ortb }); expectReplacements(repl, { '##hb_native_asset_link_id_123##': 'link' }) @@ -209,7 +209,7 @@ describe('Native creative renderer', () => { }) function runRender() { - return render({adId, native: nativeData}, {sendMessage, exc}, win, getMarkup) + return render({ adId, native: nativeData }, { sendMessage, exc }, win, getMarkup) } it('replaces placeholders in head, if present', () => { @@ -217,7 +217,7 @@ describe('Native creative renderer', () => { win.document.head.innerHTML = '##hb_native_asset_id_1##'; nativeData.ortb = { assets: [ - {id: 1, data: {value: 'repl'}} + { id: 1, data: { value: 'repl' } } ] }; return runRender().then(() => { @@ -237,7 +237,7 @@ describe('Native creative renderer', () => { getMarkup.returns(Promise.resolve('markup')); return runRender().then(() => { expect(win.document.body.innerHTML).to.eql('markup'); - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, {action: ACTION_IMP}); + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, { action: ACTION_IMP }); }) }); @@ -289,24 +289,24 @@ describe('Native creative renderer', () => { it('immediately, if document is loaded', () => { win.document.readyState = 'complete'; return runRender().then(() => { - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, {action: ACTION_RESIZE, height: 123, width: 321}) + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, { action: ACTION_RESIZE, height: 123, width: 321 }) }) }); it('on document load otherwise', () => { return runRender().then(() => { - sinon.assert.neverCalledWith(sendMessage, MESSAGE_NATIVE, sinon.match({action: ACTION_RESIZE})); + sinon.assert.neverCalledWith(sendMessage, MESSAGE_NATIVE, sinon.match({ action: ACTION_RESIZE })); win.onload(); - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, {action: ACTION_RESIZE, height: 123, width: 321}); + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, { action: ACTION_RESIZE, height: 123, width: 321 }); }) }); it('uses scrollHeight if offsetHeight is 0', () => { win.document.body.offsetHeight = 0; - win.document.documentElement = {scrollHeight: 200}; + win.document.documentElement = { scrollHeight: 200 }; return runRender().then(() => { win.onload(); - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, sinon.match({action: ACTION_RESIZE, height: 200})) + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, sinon.match({ action: ACTION_RESIZE, height: 200 })) }) }) }) @@ -326,7 +326,7 @@ describe('Native creative renderer', () => { getMarkup.returns(Promise.resolve('

')); return runRender().then(() => { win.document.querySelector('#target').click(); - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, sinon.match({action: ACTION_CLICK})); + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, sinon.match({ action: ACTION_CLICK })); }) }); @@ -334,7 +334,7 @@ describe('Native creative renderer', () => { getMarkup.returns(Promise.resolve('
')); return runRender().then(() => { win.document.querySelector('#target').click(); - sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, {action: ACTION_CLICK, assetId: '123'}) + sinon.assert.calledWith(sendMessage, MESSAGE_NATIVE, { action: ACTION_CLICK, assetId: '123' }) }); }); }); diff --git a/test/spec/debugging_spec.js b/test/spec/debugging_spec.js index 8408ceec367..20626edd7e3 100644 --- a/test/spec/debugging_spec.js +++ b/test/spec/debugging_spec.js @@ -1,6 +1,6 @@ -import {ready, loadSession, getConfig, reset, debuggingModuleLoader, debuggingControls} from '../../src/debugging.js'; -import {getGlobal} from '../../src/prebidGlobal.js'; -import {defer} from '../../src/utils/promise.js'; +import { ready, loadSession, getConfig, reset, debuggingModuleLoader, debuggingControls } from '../../src/debugging.js'; +import { getGlobal } from '../../src/prebidGlobal.js'; +import { defer } from '../../src/utils/promise.js'; import funHooks from 'fun-hooks/no-eval/index.js'; describe('Debugging', () => { @@ -20,7 +20,7 @@ describe('Debugging', () => { return scriptResult; }); alreadyInstalled = sinon.stub(); - loader = debuggingModuleLoader({alreadyInstalled, script}); + loader = debuggingModuleLoader({ alreadyInstalled, script }); }); afterEach(() => { @@ -70,7 +70,7 @@ describe('Debugging', () => { loader = defer(); hookRan = false; hook = funHooks()('sync', () => { hookRan = true }); - debugging = debuggingControls({load: sinon.stub().returns(loader.promise), hook}); + debugging = debuggingControls({ load: sinon.stub().returns(loader.promise), hook }); }) it('should delay execution of hook until module is loaded', () => { diff --git a/test/spec/e2e/banner/basic_banner_ad.spec.js b/test/spec/e2e/banner/basic_banner_ad.spec.js index 91e7b16b1eb..f230c029ed9 100644 --- a/test/spec/e2e/banner/basic_banner_ad.spec.js +++ b/test/spec/e2e/banner/basic_banner_ad.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const {setupTest, testPageURL} = require('../../../helpers/testing-utils.js'); +const { setupTest, testPageURL } = require('../../../helpers/testing-utils.js'); const TEST_PAGE_URL = testPageURL('banner.html?pbjs_debug=true'); const SYNC_PAGE_URL = testPageURL('banner_sync.html?pbjs_debug=true'); diff --git a/test/spec/e2e/modules/e2e_bidderSettings.spec.js b/test/spec/e2e/modules/e2e_bidderSettings.spec.js index a27f2be0e72..f13ab309344 100644 --- a/test/spec/e2e/modules/e2e_bidderSettings.spec.js +++ b/test/spec/e2e/modules/e2e_bidderSettings.spec.js @@ -1,5 +1,5 @@ const expect = require('chai').expect; -const {testPageURL, setupTest} = require('../../../helpers/testing-utils.js'); +const { testPageURL, setupTest } = require('../../../helpers/testing-utils.js'); const TEST_PAGE_URL = testPageURL('bidderSettings.html?pbjs_debug=true'); const CREATIVE_IFRAME_CSS_SELECTOR = 'iframe[id="google_ads_iframe_/19968336/header-bid-tag-0_0"]'; diff --git a/test/spec/fingerprinting_spec.js b/test/spec/fingerprinting_spec.js new file mode 100644 index 00000000000..f1a810fc751 --- /dev/null +++ b/test/spec/fingerprinting_spec.js @@ -0,0 +1,60 @@ +import { expect } from 'chai'; + +import { config } from 'src/config.js'; +import { getDevicePixelRatio } from 'libraries/devicePixelRatio/devicePixelRatio.js'; +import { isWebdriverEnabled } from 'libraries/webdriver/webdriver.js'; +import { getTimeZone } from 'libraries/timezone/timezone.js'; + +describe('disableFingerprintingApis', function () { + after(function () { + config.resetConfig(); + }); + + it('when devicepixelratio is disabled, getDevicePixelRatio returns 1 without reading window.devicePixelRatio', function () { + const devicePixelRatioSpy = sinon.spy(); + const mockWin = { + get devicePixelRatio() { + devicePixelRatioSpy(); + return 2; + } + }; + config.setConfig({ disableFingerprintingApis: ['devicepixelratio'] }); + const result = getDevicePixelRatio(mockWin); + expect(result).to.equal(1); + sinon.assert.notCalled(devicePixelRatioSpy); + }); + + it('when webdriver is disabled, isWebdriverEnabled returns false without reading navigator.webdriver', function () { + const webdriverSpy = sinon.spy(); + const mockWin = { + navigator: { + get webdriver() { + webdriverSpy(); + return true; + } + } + }; + config.setConfig({ disableFingerprintingApis: ['webdriver'] }); + const result = isWebdriverEnabled(mockWin); + expect(result).to.equal(false); + sinon.assert.notCalled(webdriverSpy); + }); + + it('when resolvedoptions is disabled, getTimeZone returns safe default without calling Intl.DateTimeFormat', function () { + const resolvedOptionsSpy = sinon.spy(); + const dateTimeFormatStub = sinon.stub(Intl, 'DateTimeFormat').returns({ + resolvedOptions: function () { + resolvedOptionsSpy(); + return { timeZone: 'America/New_York' }; + } + }); + try { + config.setConfig({ disableFingerprintingApis: ['resolvedoptions'] }); + const result = getTimeZone(); + expect(result).to.equal(''); + sinon.assert.notCalled(resolvedOptionsSpy); + } finally { + dateTimeFormatStub.restore(); + } + }); +}); diff --git a/test/spec/fpd/enrichment_spec.js b/test/spec/fpd/enrichment_spec.js index 8c13da6f4e2..38fa8de6f33 100644 --- a/test/spec/fpd/enrichment_spec.js +++ b/test/spec/fpd/enrichment_spec.js @@ -1,13 +1,13 @@ -import {dep, enrichFPD, getJsonLdKeywords, getMetaTagKeywords} from '../../../src/fpd/enrichment.js'; -import {hook} from '../../../src/hook.js'; -import {expect} from 'chai/index.mjs'; -import {config} from 'src/config.js'; +import { dep, enrichFPD, getJsonLdKeywords, getMetaTagKeywords } from '../../../src/fpd/enrichment.js'; +import { hook } from '../../../src/hook.js'; +import { expect } from 'chai/index.mjs'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import * as winDimensions from 'src/utils/winDimensions.js'; import * as activities from 'src/activities/rules.js' -import {CLIENT_SECTIONS} from '../../../src/fpd/oneClient.js'; -import {ACTIVITY_ACCESS_DEVICE} from '../../../src/activities/activities.js'; -import {ACTIVITY_PARAM_COMPONENT} from '../../../src/activities/params.js'; +import { CLIENT_SECTIONS } from '../../../src/fpd/oneClient.js'; +import { ACTIVITY_ACCESS_DEVICE } from '../../../src/activities/activities.js'; +import { ACTIVITY_PARAM_COMPONENT } from '../../../src/activities/params.js'; describe('FPD enrichment', () => { let sandbox; @@ -63,7 +63,7 @@ describe('FPD enrichment', () => { describe(`${section}, when set`, () => { let ortb2; beforeEach(() => { - ortb2 = {[section]: {ext: {}}} + ortb2 = { [section]: { ext: {} } } }) it('sets domain and publisher.domain', () => { @@ -188,7 +188,7 @@ describe('FPD enrichment', () => { ['dooh', 'app'].forEach(prop => { it(`should not be set when ${prop} is set`, () => { - return fpd({[prop]: {foo: 'bar'}}).then(ortb2 => { + return fpd({ [prop]: { foo: 'bar' } }).then(ortb2 => { expect(ortb2.site).to.not.exist; sinon.assert.notCalled(utils.logWarn); // make sure we don't generate "both site and app are set" warnings }) @@ -244,7 +244,7 @@ describe('FPD enrichment', () => { it('sets w/h', () => { const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions'); - getWinDimensionsStub.returns({screen: {width: 321, height: 123}}); + getWinDimensionsStub.returns({ screen: { width: 321, height: 123 } }); return fpd().then(ortb2 => { sinon.assert.match(ortb2.device, { w: 321, @@ -256,7 +256,7 @@ describe('FPD enrichment', () => { it('sets ext.vpw/vph', () => { const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions'); - getWinDimensionsStub.returns({innerWidth: 12, innerHeight: 21, screen: {}}); + getWinDimensionsStub.returns({ innerWidth: 12, innerHeight: 21, screen: {} }); return fpd().then(ortb2 => { sinon.assert.match(ortb2.device.ext, { vpw: 12, @@ -306,7 +306,7 @@ describe('FPD enrichment', () => { describe('coppa', () => { [[true, 1], [false, 0]].forEach(([cfgVal, regVal]) => { it(`is set to ${regVal} if config = ${cfgVal}`, () => { - config.setConfig({coppa: cfgVal}); + config.setConfig({ coppa: cfgVal }); return fpd().then(ortb2 => { expect(ortb2.regs.coppa).to.eql(regVal); }) @@ -335,25 +335,25 @@ describe('FPD enrichment', () => { }) }); it('uses low entropy values if uaHints is []', () => { - sandbox.stub(dep, 'getLowEntropySUA').callsFake(() => ({mock: 'sua'})); + sandbox.stub(dep, 'getLowEntropySUA').callsFake(() => ({ mock: 'sua' })); config.setConfig({ firstPartyData: { uaHints: [], } }) return fpd().then(ortb2 => { - expect(ortb2.device.sua).to.eql({mock: 'sua'}); + expect(ortb2.device.sua).to.eql({ mock: 'sua' }); }) }); it('uses high entropy values otherwise', () => { - sandbox.stub(dep, 'getHighEntropySUA').callsFake((hints) => Promise.resolve({hints})); + sandbox.stub(dep, 'getHighEntropySUA').callsFake((hints) => Promise.resolve({ hints })); config.setConfig({ firstPartyData: { uaHints: ['h1', 'h2'] } }); return fpd().then(ortb2 => { - expect(ortb2.device.sua).to.eql({hints: ['h1', 'h2']}) + expect(ortb2.device.sua).to.eql({ hints: ['h1', 'h2'] }) }) }); }); @@ -425,9 +425,9 @@ describe('FPD enrichment', () => { it('leaves only one of app, site, dooh', () => { return fpd({ - app: {p: 'val'}, - site: {p: 'val'}, - dooh: {p: 'val'} + app: { p: 'val' }, + site: { p: 'val' }, + dooh: { p: 'val' } }).then(ortb2 => { expect(ortb2.app).to.not.exist; expect(ortb2.site).to.not.exist; diff --git a/test/spec/fpd/gdpr_spec.js b/test/spec/fpd/gdpr_spec.js index a9d729e1c1e..5935bc5fd02 100644 --- a/test/spec/fpd/gdpr_spec.js +++ b/test/spec/fpd/gdpr_spec.js @@ -1,6 +1,6 @@ -import {gdprDataHandler} from '../../../src/adapterManager.js'; -import {enrichFPDHook} from '../../../modules/consentManagementTcf.js'; -import {config} from 'src/config.js'; +import { gdprDataHandler } from '../../../src/adapterManager.js'; +import { enrichFPDHook } from '../../../modules/consentManagementTcf.js'; +import { config } from 'src/config.js'; import 'src/prebid.js'; describe('GDPR FPD enrichment', () => { @@ -21,7 +21,7 @@ describe('GDPR FPD enrichment', () => { } it('sets gdpr properties from gdprDataHandler', () => { - consent = {gdprApplies: true, consentString: 'consent'}; + consent = { gdprApplies: true, consentString: 'consent' }; return callHook().then(ortb2 => { expect(ortb2.regs.ext.gdpr).to.eql(1); expect(ortb2.user.ext.consent).to.eql('consent'); @@ -35,7 +35,7 @@ describe('GDPR FPD enrichment', () => { }); it('sets user.ext.consent, but not regs.ext.gdpr, if gdprApplies is not a boolean', () => { - consent = {consentString: 'mock-consent'}; + consent = { consentString: 'mock-consent' }; return callHook().then(ortb2 => { expect(ortb2).to.eql({ user: { diff --git a/test/spec/fpd/normalize_spec.js b/test/spec/fpd/normalize_spec.js index 1f5dc1a51a1..92c92fdb303 100644 --- a/test/spec/fpd/normalize_spec.js +++ b/test/spec/fpd/normalize_spec.js @@ -1,6 +1,6 @@ -import {makeNormalizer, normalizeEIDs, normalizeFPD, normalizeSchain} from '../../../src/fpd/normalize.js'; +import { makeNormalizer, normalizeEIDs, normalizeFPD, normalizeSchain } from '../../../src/fpd/normalize.js'; import * as utils from '../../../src/utils.js'; -import {deepClone, deepSetValue} from '../../../src/utils.js'; +import { deepClone, deepSetValue } from '../../../src/utils.js'; import deepAccess from 'dlv/index.js'; describe('FPD normalization', () => { @@ -17,33 +17,33 @@ describe('FPD normalization', () => { it('should merge user.eids into user.ext.eids', () => { const fpd = { user: { - eids: [{source: 'idA'}], - ext: {eids: [{source: 'idB'}]} + eids: [{ source: 'idA' }], + ext: { eids: [{ source: 'idB' }] } } }; const result = normalizeEIDs(fpd); expect(result.user.eids).to.not.exist; expect(result.user.ext.eids).to.deep.have.members([ - {source: 'idA'}, - {source: 'idB'} + { source: 'idA' }, + { source: 'idB' } ]) }); it('should remove duplicates', () => { const fpd = { user: { - eids: [{source: 'id'}], - ext: {eids: [{source: 'id'}]} + eids: [{ source: 'id' }], + ext: { eids: [{ source: 'id' }] } } } expect(normalizeEIDs(fpd).user.ext.eids).to.eql([ - {source: 'id'} + { source: 'id' } ]) sinon.assert.called(utils.logWarn); }); it('should NOT remove duplicates if they come from the same place', () => { const fpd = { user: { - eids: [{source: 'id'}, {source: 'id'}] + eids: [{ source: 'id' }, { source: 'id' }] } } expect(normalizeEIDs(fpd).user.ext.eids.length).to.eql(2); @@ -83,7 +83,7 @@ describe('FPD normalization', () => { it('should do nothing if there is neither preferred nor fallback data', () => { ortb2.unrelated = ['data']; normalizer(ortb2); - expect(ortb2).to.eql({unrelated: ['data']}); + expect(ortb2).to.eql({ unrelated: ['data'] }); }) it(`should leave fpd unchanged if data is only in the ${t}`, () => { @@ -93,21 +93,21 @@ describe('FPD normalization', () => { }); it('should move data when it is in the fallback path', () => { - ortb2.fallback = {path: ['data']}; + ortb2.fallback = { path: ['data'] }; normalizer(ortb2); check(); }); it('should move data when it is in the preferred path', () => { - ortb2.preferred = {path: ['data']}; + ortb2.preferred = { path: ['data'] }; normalizer(ortb2); expect(deepAccess(ortb2, dest)).to.eql(deepAccess(expected, dest)); check(); }); it('should warn on conflict', () => { - ortb2.preferred = {path: ['data']}; - ortb2.fallback = {path: ['fallback']}; + ortb2.preferred = { path: ['data'] }; + ortb2.fallback = { path: ['fallback'] }; normalizer(ortb2); sinon.assert.called(utils.logWarn); check(); diff --git a/test/spec/fpd/oneClient_spec.js b/test/spec/fpd/oneClient_spec.js index 4ecde8d8a38..8c817fb9495 100644 --- a/test/spec/fpd/oneClient_spec.js +++ b/test/spec/fpd/oneClient_spec.js @@ -1,4 +1,4 @@ -import {clientSectionChecker} from '../../../src/fpd/oneClient.js'; +import { clientSectionChecker } from '../../../src/fpd/oneClient.js'; describe('onlyOneClientSection', () => { const oneClient = clientSectionChecker(); @@ -11,7 +11,7 @@ describe('onlyOneClientSection', () => { [['dooh', 'site'], 'dooh'] ].forEach(([sections, winner]) => { it(`should leave only ${winner} in request when it contains ${sections.join(', ')}`, () => { - const req = Object.fromEntries(sections.map(s => [s, {foo: 'bar'}])); + const req = Object.fromEntries(sections.map(s => [s, { foo: 'bar' }])); oneClient(req); expect(Object.keys(req)).to.eql([winner]); }) diff --git a/test/spec/fpd/rootDomain_spec.js b/test/spec/fpd/rootDomain_spec.js index b77f05d02c5..d21f4fea311 100644 --- a/test/spec/fpd/rootDomain_spec.js +++ b/test/spec/fpd/rootDomain_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai/index.js'; -import {findRootDomain, coreStorage} from 'src/fpd/rootDomain.js'; -import {canSetCookie} from '../../../src/storageManager.js'; +import { expect } from 'chai/index.js'; +import { findRootDomain, coreStorage } from 'src/fpd/rootDomain.js'; +import { canSetCookie } from '../../../src/storageManager.js'; describe('findRootDomain', function () { let sandbox, cookies, rejectDomain; diff --git a/test/spec/fpd/sua_spec.js b/test/spec/fpd/sua_spec.js index 63e0068d0ef..e4aae2ea0c7 100644 --- a/test/spec/fpd/sua_spec.js +++ b/test/spec/fpd/sua_spec.js @@ -20,7 +20,7 @@ describe('uaDataToSUA', () => { it(`should not set ${suaKey} if ${uaKey} is missing from UAData`, () => { const example = { platform: 'Windows', - brands: [{brand: 'Mock', version: 'mk'}], + brands: [{ brand: 'Mock', version: 'mk' }], mobile: true, model: 'mockModel', bitness: '64', @@ -191,7 +191,7 @@ describe('lowEntropySUAAccessor', () => { }) it('should return mobile and source', () => { - expect(getSUA(new MockUserAgentData())).to.eql({mobile: 0, source: 1}) + expect(getSUA(new MockUserAgentData())).to.eql({ mobile: 0, source: 1 }) }) }); diff --git a/test/spec/fpd/usp_spec.js b/test/spec/fpd/usp_spec.js index ddffc5df1f8..0f8dd2dc24d 100644 --- a/test/spec/fpd/usp_spec.js +++ b/test/spec/fpd/usp_spec.js @@ -1,5 +1,5 @@ -import {enrichFPDHook} from '../../../modules/consentManagementUsp.js'; -import {uspDataHandler} from '../../../src/adapterManager.js'; +import { enrichFPDHook } from '../../../modules/consentManagementUsp.js'; +import { uspDataHandler } from '../../../src/adapterManager.js'; describe('FPD enrichment USP', () => { let sandbox, consent; diff --git a/test/spec/hook_spec.js b/test/spec/hook_spec.js index a42ffbb4bb6..ef826ed3da3 100644 --- a/test/spec/hook_spec.js +++ b/test/spec/hook_spec.js @@ -1,4 +1,4 @@ -import {hook as makeHook, ignoreCallbackArg} from '../../src/hook.js'; +import { hook as makeHook, ignoreCallbackArg } from '../../src/hook.js'; describe('hooks', () => { describe('ignoreCallbackArg', () => { diff --git a/test/spec/integration/faker/googletag.js b/test/spec/integration/faker/googletag.js index a8676b500a5..4b8016c0ef1 100644 --- a/test/spec/integration/faker/googletag.js +++ b/test/spec/integration/faker/googletag.js @@ -44,7 +44,7 @@ export function makeSlot() { } export function emitEvent(eventName, params) { - (window.googletag._callbackMap[eventName] || []).forEach(eventCb => eventCb({...params, eventName})); + (window.googletag._callbackMap[eventName] || []).forEach(eventCb => eventCb({ ...params, eventName })); } export function enable() { diff --git a/test/spec/keywords_spec.js b/test/spec/keywords_spec.js index e048ead3b98..db265d7e43c 100644 --- a/test/spec/keywords_spec.js +++ b/test/spec/keywords_spec.js @@ -1,4 +1,4 @@ -import {getAllOrtbKeywords, mergeKeywords} from '../../libraries/keywords/keywords.js'; +import { getAllOrtbKeywords, mergeKeywords } from '../../libraries/keywords/keywords.js'; describe('mergeKeywords', () => { Object.entries({ @@ -66,7 +66,7 @@ describe('mergeKeywords', () => { 'three' ] } - }).forEach(([t, {input, output}]) => { + }).forEach(([t, { input, output }]) => { it(`can merge ${t}`, () => { expect(mergeKeywords(...input)).to.have.members(output); }) diff --git a/test/spec/libraries/autoplayDetection_spec.js b/test/spec/libraries/autoplayDetection_spec.js index 88c55f2b7d7..51780a245f0 100644 --- a/test/spec/libraries/autoplayDetection_spec.js +++ b/test/spec/libraries/autoplayDetection_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import sinon from 'sinon'; function loadAutoplay() { diff --git a/test/spec/libraries/boundingClientRect_spec.js b/test/spec/libraries/boundingClientRect_spec.js index ecf82876bb5..7f17a058520 100644 --- a/test/spec/libraries/boundingClientRect_spec.js +++ b/test/spec/libraries/boundingClientRect_spec.js @@ -39,7 +39,7 @@ describe('getBoundingClientRect', () => { adUnits: [], ttlBuffer: 1000, auctionId: '909090', - defer: {resolve: () => {}} + defer: { resolve: () => {} } }; getBoundingClientRect(element); diff --git a/test/spec/libraries/cmUtils_spec.js b/test/spec/libraries/cmUtils_spec.js index be2e31a8e18..4cd7276bd90 100644 --- a/test/spec/libraries/cmUtils_spec.js +++ b/test/spec/libraries/cmUtils_spec.js @@ -1,5 +1,5 @@ import * as utils from 'src/utils.js'; -import {lookupConsentData, consentManagementHook, configParser} from '../../../libraries/consentManagement/cmUtils.js'; +import { lookupConsentData, consentManagementHook, configParser } from '../../../libraries/consentManagement/cmUtils.js'; describe('consent management utils', () => { let sandbox, clock; @@ -28,7 +28,7 @@ describe('consent management utils', () => { } }, 'an error with args': { - error: Object.assign(new Error('mock-error'), {args: ['arg1', 'arg2']}), + error: Object.assign(new Error('mock-error'), { args: ['arg1', 'arg2'] }), check(logger) { sinon.assert.calledWith(logger, sinon.match('mock-error'), 'arg1', 'arg2'); } @@ -37,7 +37,7 @@ describe('consent management utils', () => { check() { } } - }).forEach(([errorDesc, {error, check: checkLogs}]) => { + }).forEach(([errorDesc, { error, check: checkLogs }]) => { describe(`when loadConsentData rejects with ${errorDesc}`, () => { beforeEach(async () => { loadResult = Promise.reject(error); @@ -47,7 +47,7 @@ describe('consent management utils', () => { }); it('should log an error and run bidsBackHandler', async () => { const bidsBackHandler = sinon.stub(); - cmHook(next, {bidsBackHandler}); + cmHook(next, { bidsBackHandler }); await loadResult.catch(() => null); sinon.assert.calledWith(utils.logError, sinon.match('Canceling auction')); sinon.assert.notCalled(next); @@ -61,10 +61,10 @@ describe('consent management utils', () => { }); describe(`when loadConsentData resolves with ${errorDesc}`, () => { function setupError() { - loadResult = Promise.resolve({error}); + loadResult = Promise.resolve({ error }); } function setupConsentAndError() { - loadResult = Promise.resolve({consentData: {'consent': 'data'}, error}); + loadResult = Promise.resolve({ consentData: { 'consent': 'data' }, error }); } Object.entries({ 'with': setupConsentAndError, @@ -73,9 +73,9 @@ describe('consent management utils', () => { describe(`${t} consent`, () => { beforeEach(setup); it('should log a warning and continue auction', async () => { - cmHook(next, {auction: 'args'}); + cmHook(next, { auction: 'args' }); await loadResult; - sinon.assert.calledWith(next, {auction: 'args'}); + sinon.assert.calledWith(next, { auction: 'args' }); checkLogs(utils.logWarn); }); }); @@ -157,14 +157,14 @@ describe('consent management utils', () => { beforeEach(() => { cmpTimeout = timeout; setupCmp.callsFake(() => { - consentDataHandler.getConsentData.returns({consent: 'data'}); + consentDataHandler.getConsentData.returns({ consent: 'data' }); return Promise.resolve(); }); }); it(`should resolve if cmp handler resolves`, async () => { - const {consentData, error} = await runLookup(); - expect(consentData).to.eql({consent: 'data'}); + const { consentData, error } = await runLookup(); + expect(consentData).to.eql({ consent: 'data' }); expect(error).to.not.exist; }); @@ -191,9 +191,9 @@ describe('consent management utils', () => { cmpTimeout = timeout; const lookup = runLookup(); clock.tick(timeout + 1); - const {consentData, error} = await lookup; - sinon.assert.calledWith(consentDataHandler.setConsentData, {consent: null}); - expect(consentData).to.eql({consent: null}) + const { consentData, error } = await lookup; + sinon.assert.calledWith(consentDataHandler.setConsentData, { consent: null }); + expect(consentData).to.eql({ consent: null }) expect(error.message).to.match(/.*CMP to load.*/) }); }); @@ -203,10 +203,10 @@ describe('consent management utils', () => { actionTimeout = timeout; const lookup = runLookup(); clock.tick(10); - setProvisionalConsent({consent: 'provisional'}); + setProvisionalConsent({ consent: 'provisional' }); clock.tick(timeout + 1); - const {consentData, error} = await lookup; - expect(consentData).to.eql({consent: 'provisional'}); + const { consentData, error } = await lookup; + expect(consentData).to.eql({ consent: 'provisional' }); expect(error.message).to.match(/.*action.*/) }); }); @@ -217,12 +217,12 @@ describe('consent management utils', () => { const lookup = runLookup().then((res) => { consentData = res.consentData; }); - setProvisionalConsent({consent: 1}); + setProvisionalConsent({ consent: 1 }); clock.tick(20); - setProvisionalConsent({consent: 2}); + setProvisionalConsent({ consent: 2 }); clock.tick(80); await lookup; - expect(consentData).to.eql({consent: 2}); + expect(consentData).to.eql({ consent: 2 }); }) }); }); @@ -242,7 +242,7 @@ describe('consent management utils', () => { setConsentData: sinon.stub() }; parseConsentData = sinon.stub().callsFake(data => data); - getNullConsent = sinon.stub().returns({consent: null}); + getNullConsent = sinon.stub().returns({ consent: null }); cmpHandlers = { iab: sinon.stub().returns(Promise.resolve()) }; @@ -269,21 +269,21 @@ describe('consent management utils', () => { }); it('should reset and return empty object when config is not an object', () => { - const result = getConsentConfig({[namespace]: 'not an object'}); + const result = getConsentConfig({ [namespace]: 'not an object' }); expect(result).to.deep.equal({}); sinon.assert.calledWith(utils.logWarn, sinon.match('config not defined')); }); describe('when module is explicitly disabled', () => { it('should reset consent data handler and return empty object when enabled is false', () => { - const result = getConsentConfig({[namespace]: {enabled: false}}); + const result = getConsentConfig({ [namespace]: { enabled: false } }); expect(result).to.deep.equal({}); sinon.assert.calledWith(utils.logWarn, sinon.match('config enabled is set to false')); }); it('should call cmpEventCleanup when enabled is false', () => { - getConsentConfig({[namespace]: {enabled: false}}); + getConsentConfig({ [namespace]: { enabled: false } }); sinon.assert.called(cmpEventCleanup); sinon.assert.calledWith(utils.logWarn, sinon.match('config enabled is set to false')); @@ -293,20 +293,20 @@ describe('consent management utils', () => { const cleanupError = new Error('Cleanup failed'); cmpEventCleanup.throws(cleanupError); - getConsentConfig({[namespace]: {enabled: false}}); + getConsentConfig({ [namespace]: { enabled: false } }); sinon.assert.called(cmpEventCleanup); sinon.assert.calledWith(utils.logError, sinon.match('Error during CMP event cleanup'), cleanupError); }); it('should not call cmpEventCleanup when enabled is true', () => { - getConsentConfig({[namespace]: {enabled: true, cmpApi: 'iab'}}); + getConsentConfig({ [namespace]: { enabled: true, cmpApi: 'iab' } }); sinon.assert.notCalled(cmpEventCleanup); }); it('should not call cmpEventCleanup when enabled is not specified', () => { - getConsentConfig({[namespace]: {cmpApi: 'iab'}}); + getConsentConfig({ [namespace]: { cmpApi: 'iab' } }); sinon.assert.notCalled(cmpEventCleanup); }); @@ -324,7 +324,7 @@ describe('consent management utils', () => { // No cmpEventCleanup provided }); - const result = configParserWithoutCleanup({[namespace]: {enabled: false}}); + const result = configParserWithoutCleanup({ [namespace]: { enabled: false } }); expect(result).to.deep.equal({}); // Should not throw error when cmpEventCleanup is undefined }); @@ -340,7 +340,7 @@ describe('consent management utils', () => { cmpEventCleanup: 'not a function' }); - const result = configParserWithNonFunction({[namespace]: {enabled: false}}); + const result = configParserWithNonFunction({ [namespace]: { enabled: false } }); expect(result).to.deep.equal({}); // Should not throw error when cmpEventCleanup is not a function }); diff --git a/test/spec/libraries/cmp/cmpClient_spec.js b/test/spec/libraries/cmp/cmpClient_spec.js index 7f78aa598fd..f647a1fa9b6 100644 --- a/test/spec/libraries/cmp/cmpClient_spec.js +++ b/test/spec/libraries/cmp/cmpClient_spec.js @@ -1,4 +1,4 @@ -import {cmpClient, MODE_CALLBACK, MODE_RETURN} from '../../../../libraries/cmp/cmpClient.js'; +import { cmpClient, MODE_CALLBACK, MODE_RETURN } from '../../../../libraries/cmp/cmpClient.js'; describe('cmpClient', () => { function mockWindow(props = {}) { @@ -15,7 +15,7 @@ describe('cmpClient', () => { } }), postMessage: sinon.stub().callsFake((msg) => { - listeners.forEach(ln => ln({data: msg})) + listeners.forEach(ln => ln({ data: msg })) }), ...props, }; @@ -24,13 +24,13 @@ describe('cmpClient', () => { } it('should return undefined when there is no CMP', () => { - expect(cmpClient({apiName: 'missing'}, mockWindow())).to.not.exist; + expect(cmpClient({ apiName: 'missing' }, mockWindow())).to.not.exist; }); it('should return undefined when parent is inaccessible', () => { const win = mockWindow(); win.top = mockWindow(); - expect(cmpClient({apiName: 'missing'}, win)).to.not.exist; + expect(cmpClient({ apiName: 'missing' }, win)).to.not.exist; }) describe('direct access', () => { @@ -39,14 +39,14 @@ describe('cmpClient', () => { mockApiFn = sinon.stub(); }) Object.entries({ - 'on same frame': () => mockWindow({mockApiFn}), - 'on parent frame': () => mockWindow({parent: mockWindow({parent: mockWindow({parent: mockWindow(), mockApiFn})})}), + 'on same frame': () => mockWindow({ mockApiFn }), + 'on parent frame': () => mockWindow({ parent: mockWindow({ parent: mockWindow({ parent: mockWindow(), mockApiFn }) }) }), }).forEach(([t, mkWindow]) => { describe(t, () => { let win, mkClient; beforeEach(() => { win = mkWindow(); - mkClient = (opts) => cmpClient(Object.assign({apiName: 'mockApiFn'}, opts), win) + mkClient = (opts) => cmpClient(Object.assign({ apiName: 'mockApiFn' }, opts), win) }); it('should mark client function as direct', () => { @@ -54,7 +54,7 @@ describe('cmpClient', () => { }); it('should find and call the CMP api function', () => { - mkClient()({command: 'mockCmd'}); + mkClient()({ command: 'mockCmd' }); sinon.assert.calledWith(mockApiFn, 'mockCmd'); }); @@ -85,14 +85,14 @@ describe('cmpClient', () => { }).forEach(([t, success]) => { it(`resolves to ${tResult} (${t})`, (done) => { cbResult = ['cbVal', success]; - mkClient({mode})({callback}).then((val) => { + mkClient({ mode })({ callback }).then((val) => { expect(val).to.equal(expectedResult); done(); }) }); it('should pass either a function or undefined as callback', () => { - mkClient({mode})({callback}); + mkClient({ mode })({ callback }); sinon.assert.calledWith(mockApiFn, sinon.match.any, sinon.match(arg => typeof arg === 'undefined' || typeof arg === 'function')) }) }); @@ -101,7 +101,7 @@ describe('cmpClient', () => { it('rejects to undefined when callback is provided and success = false', (done) => { cbResult = ['cbVal', false]; - mkClient()({callback: sinon.stub()}).catch(val => { + mkClient()({ callback: sinon.stub() }).catch(val => { expect(val).to.not.exist; done(); }) @@ -109,7 +109,7 @@ describe('cmpClient', () => { it('rejects to callback arg when callback is NOT provided, success = false, mode = MODE_CALLBACK', (done) => { cbResult = ['cbVal', false]; - mkClient({mode: MODE_CALLBACK})().catch(val => { + mkClient({ mode: MODE_CALLBACK })().catch(val => { expect(val).to.eql('cbVal'); done(); }) @@ -128,7 +128,7 @@ describe('cmpClient', () => { }) it('should use apiArgs to choose and order the arguments to pass to the API fn', () => { - mkClient({apiArgs: ['parameter', 'command']})({ + mkClient({ apiArgs: ['parameter', 'command'] })({ command: 'mockCmd', parameter: 'mockParam', callback() {} @@ -149,22 +149,22 @@ describe('cmpClient', () => { response = {}; messenger = sinon.stub().callsFake((msg) => { if (msg.mockApiCall) { - win.postMessage({mockApiReturn: {callId: msg.mockApiCall.callId, ...response}}); + win.postMessage({ mockApiReturn: { callId: msg.mockApiCall.callId, ...response } }); } }); }); function mkClient(options) { - return cmpClient(Object.assign({apiName: 'mockApi'}, options), win); + return cmpClient(Object.assign({ apiName: 'mockApi' }, options), win); } Object.entries({ 'on same frame': () => { - win = mockWindow({frames: {mockApiLocator: true}}); + win = mockWindow({ frames: { mockApiLocator: true } }); win.addEventListener('message', (evt) => messenger(evt.data)); }, 'on parent frame': () => { - win = mockWindow({parent: mockWindow({frames: {mockApiLocator: true}})}) + win = mockWindow({ parent: mockWindow({ frames: { mockApiLocator: true } }) }) win.parent.addEventListener('message', evt => messenger(evt.data)) } }).forEach(([t, setup]) => { @@ -176,7 +176,7 @@ describe('cmpClient', () => { }); it('should find and message the CMP frame', () => { - mkClient()({command: 'mockCmd', parameter: 'param'}); + mkClient()({ command: 'mockCmd', parameter: 'param' }); sinon.assert.calledWithMatch(messenger, { mockApiCall: { command: 'mockCmd', @@ -186,7 +186,7 @@ describe('cmpClient', () => { }); it('should use apiArgs to choose what to include in the message payload', () => { - mkClient({apiArgs: ['command']})({ + mkClient({ apiArgs: ['command'] })({ command: 'cmd', parameter: 'param' }); @@ -198,7 +198,7 @@ describe('cmpClient', () => { it('should not include callback in the payload, but still run it on response', () => { const cb = sinon.stub(); - mkClient({apiArgs: ['command', 'callback']})({ + mkClient({ apiArgs: ['command', 'callback'] })({ command: 'cmd', callback: cb }); @@ -208,14 +208,14 @@ describe('cmpClient', () => { it('should use callbackArgs to decide what to pass to callback', () => { const cb = sinon.stub(); - response = {a: 'one', b: 'two'}; - mkClient({callbackArgs: ['a', 'b']})({callback: cb}); + response = { a: 'one', b: 'two' }; + mkClient({ callbackArgs: ['a', 'b'] })({ callback: cb }); sinon.assert.calledWith(cb, 'one', 'two'); }) describe('should return a promise that', () => { beforeEach(() => { - response = {returnValue: 'val'} + response = { returnValue: 'val' } }) Object.entries({ 'callback': [sinon.stub(), 'undefined', undefined], @@ -228,11 +228,11 @@ describe('cmpClient', () => { describe(`when ${t} is provided`, () => { Object.entries({ 'no success flag': {}, - 'with success flag': {success: true} + 'with success flag': { success: true } }).forEach(([t, resp]) => { it(`resolves to ${tResult} (${t})`, () => { Object.assign(response, resp); - mkClient({mode})({callback}).then((val) => { + mkClient({ mode })({ callback }).then((val) => { expect(val).to.equal(expectedResult); }) }) @@ -241,7 +241,7 @@ describe('cmpClient', () => { if (mode !== MODE_RETURN) { // in return mode, the promise never rejects it(`rejects to ${tResult} when success = false`, (done) => { response.success = false; - mkClient()({mode, callback}).catch((err) => { + mkClient()({ mode, callback }).catch((err) => { expect(err).to.equal(expectedResult); done(); }); @@ -255,7 +255,7 @@ describe('cmpClient', () => { let callback, callId; function runCallback(returnValue) { - win.postMessage({mockApiReturn: {callId, returnValue}}); + win.postMessage({ mockApiReturn: { callId, returnValue } }); } beforeEach(() => { @@ -269,7 +269,7 @@ describe('cmpClient', () => { }); it('should re-use callback for messages with same callId', () => { - mkClient()({callback}); + mkClient()({ callback }); expect(callId).to.exist; runCallback('a'); runCallback('b'); @@ -278,7 +278,7 @@ describe('cmpClient', () => { }); it('should NOT re-use callback if once = true', () => { - mkClient()({callback}, true); + mkClient()({ callback }, true); expect(callId).to.exist; runCallback('a'); runCallback('b'); @@ -288,7 +288,7 @@ describe('cmpClient', () => { it('should NOT fire again after .close()', () => { const client = mkClient(); - client({callback}); + client({ callback }); runCallback('a'); client.close(); runCallback('b'); diff --git a/test/spec/libraries/currencyUtils_spec.js b/test/spec/libraries/currencyUtils_spec.js index 7eed7a5aacb..be114bfa5d4 100644 --- a/test/spec/libraries/currencyUtils_spec.js +++ b/test/spec/libraries/currencyUtils_spec.js @@ -1,5 +1,5 @@ -import {getGlobal} from 'src/prebidGlobal.js'; -import {convertCurrency, currencyCompare, currencyNormalizer} from 'libraries/currencyUtils/currency.js'; +import { getGlobal } from 'src/prebidGlobal.js'; +import { convertCurrency, currencyCompare, currencyNormalizer } from 'libraries/currencyUtils/currency.js'; describe('currency utils', () => { let sandbox; @@ -99,9 +99,9 @@ describe('currency utils', () => { compare = currencyCompare((val) => [val.amount, val.cur], currencyNormalizer(null, false, mockConvert)) }); [ - [{amount: 1, cur: 1}, {amount: 1, cur: 10}, 1], - [{amount: 10, cur: 1}, {amount: 0.1, cur: 100}, 1], - [{amount: 1, cur: 1}, {amount: 10, cur: 10}, 0], + [{ amount: 1, cur: 1 }, { amount: 1, cur: 10 }, 1], + [{ amount: 10, cur: 1 }, { amount: 0.1, cur: 100 }, 1], + [{ amount: 1, cur: 1 }, { amount: 10, cur: 10 }, 0], ].forEach(([a, b, expected]) => { it(`should compare ${a.amount}/${a.cur} and ${b.amount}/${b.cur}`, () => { expect(compare(a, b)).to.equal(expected); diff --git a/test/spec/libraries/dnt_spec.js b/test/spec/libraries/dnt_spec.js index 177542dca31..f2415dfae6e 100644 --- a/test/spec/libraries/dnt_spec.js +++ b/test/spec/libraries/dnt_spec.js @@ -1,4 +1,4 @@ -import {getDNT} from '../../../libraries/dnt/index.js'; +import { getDNT } from '../../../libraries/dnt/index.js'; describe('dnt helper', () => { let win; diff --git a/test/spec/libraries/domainOverrideToRootDomain/index_spec.js b/test/spec/libraries/domainOverrideToRootDomain/index_spec.js index d06c725803f..6109b04d97c 100644 --- a/test/spec/libraries/domainOverrideToRootDomain/index_spec.js +++ b/test/spec/libraries/domainOverrideToRootDomain/index_spec.js @@ -1,6 +1,6 @@ -import {domainOverrideToRootDomain} from 'libraries/domainOverrideToRootDomain/index.js'; -import {getStorageManager} from 'src/storageManager.js'; -import {MODULE_TYPE_UID} from '../../../../src/activities/modules.js'; +import { domainOverrideToRootDomain } from 'libraries/domainOverrideToRootDomain/index.js'; +import { getStorageManager } from 'src/storageManager.js'; +import { MODULE_TYPE_UID } from '../../../../src/activities/modules.js'; const storage = getStorageManager({ moduleName: 'test', moduleType: MODULE_TYPE_UID }); const domainOverride = domainOverrideToRootDomain(storage, 'test'); diff --git a/test/spec/libraries/greedy/greedyPromise_spec.js b/test/spec/libraries/greedy/greedyPromise_spec.js index c59f646ec5b..aa8c08f5411 100644 --- a/test/spec/libraries/greedy/greedyPromise_spec.js +++ b/test/spec/libraries/greedy/greedyPromise_spec.js @@ -1,5 +1,5 @@ -import {GreedyPromise, greedySetTimeout} from '../../../../libraries/greedy/greedyPromise.js'; -import {delay} from '../../../../src/utils/promise.js'; +import { GreedyPromise, greedySetTimeout } from '../../../../libraries/greedy/greedyPromise.js'; +import { delay } from '../../../../src/utils/promise.js'; describe('GreedyPromise', () => { it('throws when resolver is not a function', () => { @@ -113,7 +113,7 @@ describe('GreedyPromise', () => { const greedy = op(GreedyPromise); // note that we are not using `allSettled` & co to resolve our promises, // to avoid transformations those methods do under the hood - const {actual = {}, expected = {}} = {}; + const { actual = {}, expected = {} } = {}; return new Promise((resolve) => { let pending = 2; function collect(dest, slot) { diff --git a/test/spec/libraries/metadata_spec.js b/test/spec/libraries/metadata_spec.js index 0cbf066e339..5333aca09d2 100644 --- a/test/spec/libraries/metadata_spec.js +++ b/test/spec/libraries/metadata_spec.js @@ -1,4 +1,4 @@ -import {metadataRepository} from '../../../libraries/metadata/metadata.js'; +import { metadataRepository } from '../../../libraries/metadata/metadata.js'; describe('metadata', () => { let metadata; @@ -20,7 +20,7 @@ describe('metadata', () => { expect(metadata.getMetadata('bidder', 'mock')).to.eql(meta); }); it('can register and return storage disclosures', () => { - const disclosure = {timestamp: 'mock', disclosures: ['foo', 'bar']}; + const disclosure = { timestamp: 'mock', disclosures: ['foo', 'bar'] }; metadata.register('mockModule', { disclosures: { 'mock.url': disclosure @@ -42,7 +42,7 @@ describe('metadata', () => { } ] const disclosures = { - 'mock.url': {disclosures: ['foo', 'bar']} + 'mock.url': { disclosures: ['foo', 'bar'] } }; metadata.register('mockModule', { components diff --git a/test/spec/libraries/mspa/activityControls_spec.js b/test/spec/libraries/mspa/activityControls_spec.js index dcbebf9974c..ddf57c2d440 100644 --- a/test/spec/libraries/mspa/activityControls_spec.js +++ b/test/spec/libraries/mspa/activityControls_spec.js @@ -1,5 +1,5 @@ -import {mspaRule, setupRules, isTransmitUfpdConsentDenied, isTransmitGeoConsentDenied, isBasicConsentDenied, sensitiveNoticeIs, isConsentDenied} from '../../../../libraries/mspa/activityControls.js'; -import {ruleRegistry} from '../../../../src/activities/rules.js'; +import { mspaRule, setupRules, isTransmitUfpdConsentDenied, isTransmitGeoConsentDenied, isBasicConsentDenied, sensitiveNoticeIs, isConsentDenied } from '../../../../libraries/mspa/activityControls.js'; +import { ruleRegistry } from '../../../../src/activities/rules.js'; describe('Consent interpretation', () => { function mkConsent(flags) { @@ -124,7 +124,7 @@ describe('Consent interpretation', () => { versions: [2] } - }).forEach(([t, {flagNo, consents, versions}]) => { + }).forEach(([t, { flagNo, consents, versions }]) => { describe(t, () => { Object.entries(consents).forEach(([flagValue, shouldBeDenied]) => { const flagDescription = ({ @@ -236,7 +236,7 @@ describe('mspaRule', () => { }); it('should deny when consent is using version other than 1/2', () => { - consent = {Version: 3}; + consent = { Version: 3 }; expect(mkRule()().allow).to.equal(false); }) @@ -246,7 +246,7 @@ describe('mspaRule', () => { }).forEach(([t, denied]) => { it(`should check if deny fn ${t}`, () => { denies.returns(denied); - consent = {mock: 'value', Version: 1}; + consent = { mock: 'value', Version: 1 }; const result = mkRule()(); sinon.assert.calledWith(denies, consent); if (denied) { @@ -290,7 +290,7 @@ describe('setupRules', () => { }); it('should accept already flattened section data', () => { - consent.parsedSections.mockApi = {flat: 'consent', Version: 1}; + consent.parsedSections.mockApi = { flat: 'consent', Version: 1 }; runSetup('mockApi', [1]); isAllowed('mockActivity', {}); sinon.assert.calledWith(rules.mockActivity, consent.parsedSections.mockApi) @@ -308,11 +308,11 @@ describe('setupRules', () => { }); it('should pass flattened consent through normalizeConsent', () => { - const normalize = sinon.stub().returns({normalized: 'consent', Version: 1}) + const normalize = sinon.stub().returns({ normalized: 'consent', Version: 1 }) runSetup('mockApi', [1], normalize); expect(isAllowed('mockActivity', {})).to.equal(false); - sinon.assert.calledWith(normalize, {mock: 'consent', Version: 1}); - sinon.assert.calledWith(rules.mockActivity, {normalized: 'consent', Version: 1}); + sinon.assert.calledWith(normalize, { mock: 'consent', Version: 1 }); + sinon.assert.calledWith(rules.mockActivity, { normalized: 'consent', Version: 1 }); }); it('should return a function that unregisters activity controls', () => { diff --git a/test/spec/libraries/percentInView_spec.js b/test/spec/libraries/percentInView_spec.js new file mode 100644 index 00000000000..7405e95f95d --- /dev/null +++ b/test/spec/libraries/percentInView_spec.js @@ -0,0 +1,40 @@ +import { getViewportOffset } from '../../../libraries/percentInView/percentInView.js'; + +describe('percentInView', () => { + describe('getViewportOffset', () => { + function mockWindow(offsets = []) { + let win, leaf, child; + win = leaf = {}; + for (const [x, y] of offsets) { + win.frameElement = { + getBoundingClientRect() { + return { left: x, top: y }; + } + }; + child = win; + win = {}; + child.parent = win; + } + return leaf; + } + it('returns 0, 0 for the top window', () => { + expect(getViewportOffset(mockWindow())).to.eql({ x: 0, y: 0 }); + }); + + it('returns frame offset for a direct child', () => { + expect(getViewportOffset(mockWindow([[10, 20]]))).to.eql({ x: 10, y: 20 }); + }); + it('returns cumulative offests for descendants', () => { + expect(getViewportOffset(mockWindow([[10, 20], [20, 30]]))).to.eql({ x: 30, y: 50 }); + }); + it('does not choke when parent is not accessible', () => { + const win = mockWindow([[10, 20]]); + Object.defineProperty(win, 'frameElement', { + get() { + throw new Error(); + } + }); + expect(getViewportOffset(win)).to.eql({ x: 0, y: 0 }); + }); + }); +}); diff --git a/test/spec/libraries/placementPositionInfo_spec.js b/test/spec/libraries/placementPositionInfo_spec.js new file mode 100644 index 00000000000..91aee5c6d81 --- /dev/null +++ b/test/spec/libraries/placementPositionInfo_spec.js @@ -0,0 +1,458 @@ +import { getPlacementPositionUtils } from '../../../libraries/placementPositionInfo/placementPositionInfo.js'; +import * as utils from '../../../src/utils.js'; +import * as boundingClientRectLib from '../../../libraries/boundingClientRect/boundingClientRect.js'; +import * as percentInViewLib from '../../../libraries/percentInView/percentInView.js'; +import * as winDimensions from 'src/utils/winDimensions.js'; + +import assert from 'assert'; +import sinon from 'sinon'; + +describe('placementPositionInfo', function () { + let sandbox; + let canAccessWindowTopStub; + let getWindowTopStub; + let getWindowSelfStub; + let getBoundingClientRectStub; + let percentInViewStub; + let cleanObjStub; + + let mockDocument; + let mockWindow; + let viewportOffset + + beforeEach(function () { + sandbox = sinon.createSandbox(); + + mockDocument = { + getElementById: sandbox.stub().returns(null), + getElementsByTagName: sandbox.stub().returns([]), + body: { scrollHeight: 2000, offsetHeight: 1800 }, + documentElement: { clientHeight: 1900, scrollHeight: 2100, offsetHeight: 1950 }, + visibilityState: 'visible' + }; + + mockWindow = { + innerHeight: 800, + document: mockDocument + }; + + canAccessWindowTopStub = sandbox.stub(utils, 'canAccessWindowTop').returns(true); + getWindowTopStub = sandbox.stub(utils, 'getWindowTop').returns(mockWindow); + getWindowSelfStub = sandbox.stub(utils, 'getWindowSelf').returns(mockWindow); + getBoundingClientRectStub = sandbox.stub(boundingClientRectLib, 'getBoundingClientRect'); + percentInViewStub = sandbox.stub(percentInViewLib, 'getViewability'); + cleanObjStub = sandbox.stub(utils, 'cleanObj').callsFake(obj => obj); + sandbox.stub(winDimensions, 'getWinDimensions').returns(mockWindow); + viewportOffset = { x: 0, y: 0 }; + sandbox.stub(percentInViewLib, 'getViewportOffset').callsFake(() => viewportOffset); + }); + + afterEach(function () { + sandbox.restore(); + }); + + describe('getPlacementPositionUtils', function () { + it('should return an object with getPlacementInfo and getPlacementEnv functions', function () { + const result = getPlacementPositionUtils(); + + assert.strictEqual(typeof result.getPlacementInfo, 'function'); + assert.strictEqual(typeof result.getPlacementEnv, 'function'); + }); + + it('should use window top when accessible', function () { + canAccessWindowTopStub.returns(true); + getPlacementPositionUtils(); + + assert.ok(getWindowTopStub.called); + }); + + it('should use window self when top is not accessible', function () { + canAccessWindowTopStub.returns(false); + getPlacementPositionUtils(); + + assert.ok(getWindowSelfStub.called); + }); + }); + + describe('getPlacementInfo', function () { + let getPlacementInfo; + let mockElement; + + beforeEach(function () { + mockElement = { id: 'test-ad-unit' }; + mockDocument.getElementById.returns(mockElement); + + getBoundingClientRectStub.returns({ + top: 100, + bottom: 200, + height: 100, + width: 300 + }); + + percentInViewStub.returns(50); + + const placementUtils = getPlacementPositionUtils(); + getPlacementInfo = placementUtils.getPlacementInfo; + }); + + it('should return placement info with all required fields', function () { + const bidReq = { + adUnitCode: 'test-ad-unit', + auctionsCount: 5, + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.AuctionsCount, 5); + assert.strictEqual(typeof result.DistanceToView, 'number'); + assert.strictEqual(typeof result.PlacementPercentView, 'number'); + assert.strictEqual(typeof result.ElementHeight, 'number'); + }); + + it('should calculate distanceToView as 0 when element is in viewport', function () { + getBoundingClientRectStub.returns({ + top: 100, + bottom: 200, + height: 100 + }); + + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 0); + }); + + it('should calculate positive distanceToView when element is below viewport', function () { + getBoundingClientRectStub.returns({ + top: 1000, + bottom: 1100, + height: 100 + }); + + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 200); + }); + + it('should calculate negative distanceToView when element is above viewport', function () { + getBoundingClientRectStub.returns({ + top: -200, + bottom: -100, + height: 100 + }); + + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, -100); + }); + + it('should handle null element gracefully', function () { + mockDocument.getElementById.returns(null); + + const bidReq = { + adUnitCode: 'non-existent-unit', + sizes: [[300, 250]] + }; + + const placementUtils = getPlacementPositionUtils(); + const result = placementUtils.getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 0); + assert.strictEqual(result.ElementHeight, 1); + }); + + it('should not call getViewability when element is null', function () { + mockDocument.getElementById.returns(null); + + const bidReq = { + adUnitCode: 'non-existent-unit', + sizes: [[300, 250]] + }; + + const placementUtils = getPlacementPositionUtils(); + placementUtils.getPlacementInfo(bidReq); + + assert.ok(!percentInViewStub.called, 'getViewability should not be called with null element'); + }); + + it('should handle empty sizes array', function () { + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [] + }; + + const result = getPlacementInfo(bidReq); + + assert.ok(!isNaN(result.PlacementPercentView), 'PlacementPercentView should not be NaN'); + }); + + it('should handle undefined sizes', function () { + const bidReq = { + adUnitCode: 'test-ad-unit' + }; + + const result = getPlacementInfo(bidReq); + + assert.ok(!isNaN(result.PlacementPercentView), 'PlacementPercentView should not be NaN'); + }); + + it('should select the smallest size by area', function () { + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[728, 90], [300, 250], [160, 600]] + }; + + getPlacementInfo(bidReq); + + const percentInViewCall = percentInViewStub.getCall(0); + const sizeArg = percentInViewCall.args[2]; + + assert.strictEqual(sizeArg.w, 728); + assert.strictEqual(sizeArg.h, 90); + }); + + it('should use ElementHeight from bounding rect', function () { + getBoundingClientRectStub.returns({ + top: 100, + bottom: 350, + height: 250 + }); + + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.ElementHeight, 250); + }); + + it('should default ElementHeight to 1 when height is 0', function () { + getBoundingClientRectStub.returns({ + top: 100, + bottom: 100, + height: 0 + }); + + const bidReq = { + adUnitCode: 'test-ad-unit', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.ElementHeight, 1); + }); + }); + + describe('getPlacementEnv', function () { + let getPlacementEnv; + let performanceNowStub; + + beforeEach(function () { + performanceNowStub = sandbox.stub(performance, 'now').returns(1234.567); + + const placementUtils = getPlacementPositionUtils(); + getPlacementEnv = placementUtils.getPlacementEnv; + }); + + it('should return environment info with all required fields', function () { + const result = getPlacementEnv(); + + assert.strictEqual(typeof result.TimeFromNavigation, 'number'); + assert.strictEqual(typeof result.TabActive, 'boolean'); + assert.strictEqual(typeof result.PageHeight, 'number'); + assert.strictEqual(typeof result.ViewportHeight, 'number'); + }); + + it('should return TimeFromNavigation as floored performance.now()', function () { + performanceNowStub.returns(5678.999); + + const placementUtils = getPlacementPositionUtils(); + const result = placementUtils.getPlacementEnv(); + + assert.strictEqual(result.TimeFromNavigation, 5678); + }); + + it('should return TabActive as true when document is visible', function () { + const result = getPlacementEnv(); + + assert.strictEqual(result.TabActive, true); + }); + + it('should return TabActive as false when document is hidden', function () { + sandbox.restore(); + sandbox = sinon.createSandbox(); + + const hiddenMockDocument = { + getElementById: sandbox.stub().returns(null), + getElementsByTagName: sandbox.stub().returns([]), + body: { scrollHeight: 1000, offsetHeight: 1000 }, + documentElement: { clientHeight: 1000, scrollHeight: 1000, offsetHeight: 1000 }, + visibilityState: 'hidden' + }; + + const hiddenMockWindow = { + innerHeight: 800, + document: hiddenMockDocument + }; + + sandbox.stub(utils, 'canAccessWindowTop').returns(true); + sandbox.stub(utils, 'getWindowTop').returns(hiddenMockWindow); + sandbox.stub(utils, 'getWindowSelf').returns(hiddenMockWindow); + sandbox.stub(utils, 'cleanObj').callsFake(obj => obj); + sandbox.stub(performance, 'now').returns(1000); + + const freshUtils = getPlacementPositionUtils(); + const result = freshUtils.getPlacementEnv(); + + assert.strictEqual(result.TabActive, false); + }); + + it('should return ViewportHeight from window.innerHeight', function () { + const result = getPlacementEnv(); + + assert.strictEqual(result.ViewportHeight, 800); + }); + + it('should return max PageHeight from all document height properties', function () { + const result = getPlacementEnv(); + + assert.strictEqual(result.PageHeight, 2100); + }); + }); + + describe('getViewableDistance edge cases', function () { + let getPlacementInfo; + + beforeEach(function () { + mockDocument.getElementById.returns({ id: 'test' }); + percentInViewStub.returns(0); + + const placementUtils = getPlacementPositionUtils(); + getPlacementInfo = placementUtils.getPlacementInfo; + }); + + it('should handle getBoundingClientRect returning null', function () { + getBoundingClientRectStub.returns(null); + + const bidReq = { + adUnitCode: 'test', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 0); + assert.strictEqual(result.ElementHeight, 1); + }); + + it('should handle element exactly at viewport bottom edge', function () { + getBoundingClientRectStub.returns({ + top: 800, + bottom: 900, + height: 100 + }); + + const bidReq = { + adUnitCode: 'test', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 0); + }); + + it('should handle element exactly at viewport top edge', function () { + getBoundingClientRectStub.returns({ + top: 0, + bottom: 100, + height: 100 + }); + + const bidReq = { + adUnitCode: 'test', + sizes: [[300, 250]] + }; + + const result = getPlacementInfo(bidReq); + + assert.strictEqual(result.DistanceToView, 0); + }); + }); + + describe('iframe coordinate translation', function () { + beforeEach(() => { + mockDocument.getElementById = sandbox.stub().returns({ id: 'test' }); + mockWindow.innerHeight = 1000; + mockDocument.body = { + scrollHeight: 2000, offsetHeight: 1800 + } + mockDocument.documentElement = { clientHeight: 1900, scrollHeight: 2100, offsetHeight: 1950 } + }); + it('should apply iframe offset when running inside a friendly iframe', function () { + viewportOffset = { y: 200 }; + + getBoundingClientRectStub.callsFake((el) => { + return { top: 100, bottom: 200, height: 100 }; + }); + + const placementUtils = getPlacementPositionUtils(); + const result = placementUtils.getPlacementInfo({ + adUnitCode: 'test', + sizes: [[300, 250]] + }); + + assert.strictEqual(result.DistanceToView, 0); + }); + + it('should calculate correct distance when element is below viewport with iframe offset', function () { + viewportOffset = { y: 500 }; + + getBoundingClientRectStub.callsFake((el) => { + return { top: 600, bottom: 700, height: 100 }; + }); + + const placementUtils = getPlacementPositionUtils(); + const result = placementUtils.getPlacementInfo({ + adUnitCode: 'test', + sizes: [[300, 250]] + }); + + assert.strictEqual(result.DistanceToView, 100); + }); + + it('should calculate negative distance when element is above viewport with iframe offset', function () { + viewportOffset = { y: -600 }; + + getBoundingClientRectStub.callsFake((el) => { + return { top: 100, bottom: 200, height: 100 }; + }); + + const placementUtils = getPlacementPositionUtils(); + const result = placementUtils.getPlacementInfo({ + adUnitCode: 'test', + sizes: [[300, 250]] + }); + + assert.strictEqual(result.DistanceToView, -400); + }); + }); +}); diff --git a/test/spec/libraries/precisoUtils/bidNativeUtils_spec.js b/test/spec/libraries/precisoUtils/bidNativeUtils_spec.js index 1993ab3665a..1b163b513c8 100644 --- a/test/spec/libraries/precisoUtils/bidNativeUtils_spec.js +++ b/test/spec/libraries/precisoUtils/bidNativeUtils_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { NATIVE } from '../../../../src/mediaTypes.js'; import { interpretNativeBid, OPENRTB } from '../../../../libraries/precisoUtils/bidNativeUtils.js'; diff --git a/test/spec/libraries/precisoUtils/bidUtilsCommon_spec.js b/test/spec/libraries/precisoUtils/bidUtilsCommon_spec.js index ad7243cb875..03b3b219cc5 100644 --- a/test/spec/libraries/precisoUtils/bidUtilsCommon_spec.js +++ b/test/spec/libraries/precisoUtils/bidUtilsCommon_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { BANNER } from '../../../../src/mediaTypes.js'; import * as utils from '../../../../src/utils.js'; diff --git a/test/spec/libraries/processResponse_spec.js b/test/spec/libraries/processResponse_spec.js index 99d20c69c77..9ca5844496e 100644 --- a/test/spec/libraries/processResponse_spec.js +++ b/test/spec/libraries/processResponse_spec.js @@ -1,5 +1,5 @@ import { getBidFromResponse } from '../../../libraries/processResponse/index.js'; -import {expect} from 'chai/index.js'; +import { expect } from 'chai/index.js'; describe('processResponse', function () { const respItem = { diff --git a/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js b/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js index 686a9b1ad30..2de026f86bc 100644 --- a/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js +++ b/test/spec/libraries/pubmaticUtils/plugins/floorProvider_spec.js @@ -2,7 +2,7 @@ import sinon from 'sinon'; import * as floorProvider from '../../../../../libraries/pubmaticUtils/plugins/floorProvider.js'; import * as priceFloors from '../../../../../modules/priceFloors.js'; import * as pubmaticUtils from '../../../../../libraries/pubmaticUtils/pubmaticUtils.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; describe('FloorProvider', () => { const floorsobj = { @@ -91,7 +91,7 @@ describe('FloorProvider', () => { getConfigByName: () => floorsobj }); - const req = {err: 4}; + const req = { err: 4 }; const result = await floorProvider.processBidRequest(req); expect(result).to.equal(req); diff --git a/test/spec/libraries/sizeUtils_spec.js b/test/spec/libraries/sizeUtils_spec.js index 37e089f39ad..e2f69a6c826 100644 --- a/test/spec/libraries/sizeUtils_spec.js +++ b/test/spec/libraries/sizeUtils_spec.js @@ -1,5 +1,5 @@ -import {getAdUnitSizes} from '../../../libraries/sizeUtils/sizeUtils.js'; -import {expect} from 'chai/index.js'; +import { getAdUnitSizes } from '../../../libraries/sizeUtils/sizeUtils.js'; +import { expect } from 'chai/index.js'; describe('getAdUnitSizes', function () { it('returns an empty response when adUnits is undefined', function () { @@ -8,23 +8,23 @@ describe('getAdUnitSizes', function () { }); it('returns an empty array when invalid data is present in adUnit object', function () { - const sizes = getAdUnitSizes({sizes: 300}); + const sizes = getAdUnitSizes({ sizes: 300 }); expect(sizes).to.deep.equal([]); }); it('retuns an array of arrays when reading from adUnit.sizes', function () { - let sizes = getAdUnitSizes({sizes: [300, 250]}); + let sizes = getAdUnitSizes({ sizes: [300, 250] }); expect(sizes).to.deep.equal([[300, 250]]); - sizes = getAdUnitSizes({sizes: [[300, 250], [300, 600]]}); + sizes = getAdUnitSizes({ sizes: [[300, 250], [300, 600]] }); expect(sizes).to.deep.equal([[300, 250], [300, 600]]); }); it('returns an array of arrays when reading from adUnit.mediaTypes.banner.sizes', function () { - let sizes = getAdUnitSizes({mediaTypes: {banner: {sizes: [300, 250]}}}); + let sizes = getAdUnitSizes({ mediaTypes: { banner: { sizes: [300, 250] } } }); expect(sizes).to.deep.equal([[300, 250]]); - sizes = getAdUnitSizes({mediaTypes: {banner: {sizes: [[300, 250], [300, 600]]}}}); + sizes = getAdUnitSizes({ mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } } }); expect(sizes).to.deep.equal([[300, 250], [300, 600]]); }); }); diff --git a/test/spec/libraries/storageDisclosure_spec.js b/test/spec/libraries/storageDisclosure_spec.js index 1f848504ee2..fa345b6115c 100644 --- a/test/spec/libraries/storageDisclosure_spec.js +++ b/test/spec/libraries/storageDisclosure_spec.js @@ -1,5 +1,5 @@ -import {getStorageDisclosureSummary} from '../../../libraries/storageDisclosure/summary.js'; -import {dynamicDisclosureCollector} from '../../../modules/storageControl.js'; +import { getStorageDisclosureSummary } from '../../../libraries/storageDisclosure/summary.js'; +import { dynamicDisclosureCollector } from '../../../modules/storageControl.js'; describe('storageDisclosure', () => { let moduleMeta; @@ -38,7 +38,7 @@ describe('storageDisclosure', () => { disclosures: { url1: { disclosures: [ - {identifier: 'foo'} + { identifier: 'foo' } ] } } @@ -47,7 +47,7 @@ describe('storageDisclosure', () => { disclosures: { url2: { disclosures: [ - {identifier: 'bar'} + { identifier: 'bar' } ] } } @@ -71,7 +71,7 @@ describe('storageDisclosure', () => { const disclosures = { url: { disclosures: [ - {identifier: 'foo'} + { identifier: 'foo' } ] } } diff --git a/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js b/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js index 85ea1131db4..73055521549 100644 --- a/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js +++ b/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js @@ -516,7 +516,7 @@ describe('TeqBlazeBidderUtils', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -525,9 +525,7 @@ describe('TeqBlazeBidderUtils', function () { expect(syncData[0].url).to.equal(`https://${DOMAIN}/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0`) }); it('Should return array of objects with proper sync config , include CCPA', function () { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -536,7 +534,7 @@ describe('TeqBlazeBidderUtils', function () { expect(syncData[0].url).to.equal(`https://${DOMAIN}/image?pbjs=1&ccpa_consent=1---&coppa=0`) }); it('Should return array of objects with proper sync config , include GPP', function () { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/libraries/timeoutQueue_spec.js b/test/spec/libraries/timeoutQueue_spec.js index ab8d20aa97d..b290325bcaa 100644 --- a/test/spec/libraries/timeoutQueue_spec.js +++ b/test/spec/libraries/timeoutQueue_spec.js @@ -1,5 +1,5 @@ -import {timeoutQueue} from '../../../libraries/timeoutQueue/timeoutQueue.js'; -import {expect} from 'chai/index.js'; +import { timeoutQueue } from '../../../libraries/timeoutQueue/timeoutQueue.js'; +import { expect } from 'chai/index.js'; describe('timeoutQueue', () => { let clock; diff --git a/test/spec/libraries/urlUtils_spec.js b/test/spec/libraries/urlUtils_spec.js index 9dd66b05407..43629a439ef 100644 --- a/test/spec/libraries/urlUtils_spec.js +++ b/test/spec/libraries/urlUtils_spec.js @@ -1,4 +1,4 @@ -import {tryAppendQueryString} from '../../../libraries/urlUtils/urlUtils.js'; +import { tryAppendQueryString } from '../../../libraries/urlUtils/urlUtils.js'; import assert from 'assert'; describe('tryAppendQueryString', function () { diff --git a/test/spec/libraries/vastTrackers_spec.js b/test/spec/libraries/vastTrackers_spec.js index ddd80e98f9d..e0e3db9cae4 100644 --- a/test/spec/libraries/vastTrackers_spec.js +++ b/test/spec/libraries/vastTrackers_spec.js @@ -7,8 +7,8 @@ import { reset, cacheVideoBidHook, disable } from 'libraries/vastTrackers/vastTrackers.js'; -import {MODULE_TYPE_ANALYTICS} from '../../../src/activities/modules.js'; -import {AuctionIndex} from '../../../src/auctionIndex.js'; +import { MODULE_TYPE_ANALYTICS } from '../../../src/activities/modules.js'; +import { AuctionIndex } from '../../../src/auctionIndex.js'; describe('vast trackers', () => { let sandbox, tracker, auction, bid, bidRequest, index; @@ -28,17 +28,17 @@ describe('vast trackers', () => { return 'aid'; }, getProperties() { - return {auction: 'props'}; + return { auction: 'props' }; }, getBidRequests() { - return [{bids: [bidRequest]}] + return [{ bids: [bidRequest] }] } }; sandbox = sinon.createSandbox(); index = new AuctionIndex(() => [auction]); tracker = sinon.stub().callsFake(function (bidResponse) { return [ - {'event': 'impressions', 'url': `https://vasttracking.mydomain.com/vast?cpm=${bidResponse.cpm}`} + { 'event': 'impressions', 'url': `https://vasttracking.mydomain.com/vast?cpm=${bidResponse.cpm}` } ]; }); registerVastTrackers(MODULE_TYPE_ANALYTICS, 'test', tracker); @@ -51,27 +51,27 @@ describe('vast trackers', () => { after(disable); it('insert into tracker list', function () { - const trackers = getVastTrackers(bid, {index}); + const trackers = getVastTrackers(bid, { index }); expect(trackers).to.be.a('map'); expect(trackers.get('impressions')).to.exists; expect(trackers.get('impressions').has('https://vasttracking.mydomain.com/vast?cpm=1')).to.be.true; }); it('insert trackers in vastXml', function () { - const trackers = getVastTrackers(bid, {index}); + const trackers = getVastTrackers(bid, { index }); let vastXml = ''; vastXml = insertVastTrackers(trackers, vastXml); expect(vastXml).to.equal(''); }); it('should pass request and auction properties to trackerFn', () => { - const bid = {requestId: 'bid', auctionId: 'aid'}; - getVastTrackers(bid, {index}); - sinon.assert.calledWith(tracker, bid, sinon.match({auction: auction.getProperties(), bidRequest})) + const bid = { requestId: 'bid', auctionId: 'aid' }; + getVastTrackers(bid, { index }); + sinon.assert.calledWith(tracker, bid, sinon.match({ auction: auction.getProperties(), bidRequest })) }) it('test addImpUrlToTrackers', function () { - const trackers = addImpUrlToTrackers({'vastImpUrl': 'imptracker.com'}, getVastTrackers(bid, {index})); + const trackers = addImpUrlToTrackers({ 'vastImpUrl': 'imptracker.com' }, getVastTrackers(bid, { index })); expect(trackers).to.be.a('map'); expect(trackers.get('impressions')).to.exists; expect(trackers.get('impressions').has('imptracker.com')).to.be.true; @@ -79,7 +79,7 @@ describe('vast trackers', () => { if (FEATURES.VIDEO) { it('should add trackers to bid response', () => { - cacheVideoBidHook({index})(sinon.stub(), 'au', bid); + cacheVideoBidHook({ index })(sinon.stub(), 'au', bid); expect(bid.vastImpUrl).to.eql([ 'https://vasttracking.mydomain.com/vast?cpm=1' ]) diff --git a/test/spec/libraries/weakStore_spec.js b/test/spec/libraries/weakStore_spec.js index 407b83391ef..f249fdf3f7d 100644 --- a/test/spec/libraries/weakStore_spec.js +++ b/test/spec/libraries/weakStore_spec.js @@ -1,4 +1,4 @@ -import {weakStore} from '../../../libraries/weakStore/weakStore.js'; +import { weakStore } from '../../../libraries/weakStore/weakStore.js'; describe('weakStore', () => { let targets, store; @@ -18,7 +18,7 @@ describe('weakStore', () => { }); it('inits to given value', () => { - expect(store('id', {initial: 'value'})).to.eql({'initial': 'value'}); + expect(store('id', { initial: 'value' })).to.eql({ 'initial': 'value' }); }); it('returns the same object as long as the target does not change', () => { @@ -26,7 +26,7 @@ describe('weakStore', () => { }); it('ignores init value if already initialized', () => { - store('id', {initial: 'value'}); - expect(store('id', {second: 'value'})).to.eql({initial: 'value'}); + store('id', { initial: 'value' }); + expect(store('id', { second: 'value' })).to.eql({ initial: 'value' }); }) }); diff --git a/test/spec/modules/1plusXRtdProvider_spec.js b/test/spec/modules/1plusXRtdProvider_spec.js index b971fda6521..00243c7ae38 100644 --- a/test/spec/modules/1plusXRtdProvider_spec.js +++ b/test/spec/modules/1plusXRtdProvider_spec.js @@ -1,5 +1,5 @@ import assert from 'assert'; -import {config} from 'src/config'; +import { config } from 'src/config'; import { buildOrtb2Updates, extractConfig, @@ -11,7 +11,7 @@ import { setTargetingDataToConfig, updateBidderConfig, } from 'modules/1plusXRtdProvider'; -import {deepClone} from '../../../src/utils.js'; +import { deepClone } from '../../../src/utils.js'; import { STORAGE_TYPE_COOKIES, STORAGE_TYPE_LOCALSTORAGE } from 'src/storageManager.js'; import { server } from 'test/mocks/xhr.js'; diff --git a/test/spec/modules/33acrossAnalyticsAdapter_spec.js b/test/spec/modules/33acrossAnalyticsAdapter_spec.js index b31117e00c4..03b6e7981fa 100644 --- a/test/spec/modules/33acrossAnalyticsAdapter_spec.js +++ b/test/spec/modules/33acrossAnalyticsAdapter_spec.js @@ -422,7 +422,7 @@ describe('33acrossAnalyticsAdapter:', function () { const timeout = 2000; this.enableAnalytics({ timeout }); - performStandardAuction({exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd'] }); sandbox.clock.tick(timeout + 1000); @@ -435,7 +435,7 @@ describe('33acrossAnalyticsAdapter:', function () { const request = getMockEvents().prebid[0].BID_REQUESTED[0]; const bidToTimeout = request.bids[0]; - performStandardAuction({exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd'] }); sandbox.clock.tick(1); events.emit(EVENTS.BID_TIMEOUT, [{ auctionId: request.auctionId, @@ -455,7 +455,7 @@ describe('33acrossAnalyticsAdapter:', function () { it('logs an error', function () { this.enableAnalytics(); - performStandardAuction({exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'slotRenderEnded', 'auctionEnd'] }); sandbox.clock.tick(this.defaultTimeout + 1000); @@ -470,7 +470,7 @@ describe('33acrossAnalyticsAdapter:', function () { const timeout = POST_GAM_TIMEOUT + 2000; this.enableAnalytics({ timeout }); - performStandardAuction({exclude: ['bidWon', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'auctionEnd'] }); sandbox.clock.tick(POST_GAM_TIMEOUT + 1); assert.strictEqual(navigator.sendBeacon.callCount, 1); @@ -482,7 +482,7 @@ describe('33acrossAnalyticsAdapter:', function () { const timeout = POST_GAM_TIMEOUT + 2000; this.enableAnalytics({ timeout }); - performStandardAuction({exclude: ['bidWon', 'auctionEnd'], useSlotElementIds: true}); + performStandardAuction({ exclude: ['bidWon', 'auctionEnd'], useSlotElementIds: true }); sandbox.clock.tick(POST_GAM_TIMEOUT + 1); assert.strictEqual(navigator.sendBeacon.callCount, 1); @@ -493,7 +493,7 @@ describe('33acrossAnalyticsAdapter:', function () { const timeout = POST_GAM_TIMEOUT + 2000; this.enableAnalytics({ timeout }); - performStandardAuction({exclude: ['bidWon', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'auctionEnd'] }); sandbox.clock.tick(POST_GAM_TIMEOUT - 1); assert.strictEqual(navigator.sendBeacon.callCount, 0); @@ -526,7 +526,7 @@ describe('33acrossAnalyticsAdapter:', function () { this.enableAnalytics(); - performStandardAuction({exclude: ['auctionEnd']}); + performStandardAuction({ exclude: ['auctionEnd'] }); sandbox.clock.tick(this.defaultTimeout + 1000); const incompleteSentBid = JSON.parse(navigator.sendBeacon.firstCall.args[1]).auctions[0].adUnits[1].bids[0]; @@ -538,7 +538,7 @@ describe('33acrossAnalyticsAdapter:', function () { this.enableAnalytics(); - performStandardAuction({exclude: ['bidWon', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'auctionEnd'] }); sandbox.clock.tick(this.defaultTimeout + 1000); const incompleteSentBid = JSON.parse(navigator.sendBeacon.firstCall.args[1]).auctions[0].adUnits[1].bids[0]; @@ -551,7 +551,7 @@ describe('33acrossAnalyticsAdapter:', function () { const endpoint = faker.internet.url(); this.enableAnalytics({ endpoint }); - performStandardAuction({exclude: ['bidWon', 'auctionEnd']}); + performStandardAuction({ exclude: ['bidWon', 'auctionEnd'] }); sandbox.clock.tick(this.defaultTimeout + 1000); assert.calledWith(log.info, `Analytics report sent to ${endpoint}`); @@ -616,7 +616,7 @@ describe('33acrossAnalyticsAdapter:', function () { context('and the Google Ad Manager timeout has elapsed', function () { it('completes the transaction', function () { const timeout = POST_GAM_TIMEOUT + 2000; - this.enableAnalytics({timeout}); + this.enableAnalytics({ timeout }); const { prebid: [auction], gam } = getMockEvents(); const slotRenderEnded = gam.slotRenderEnded[0]; diff --git a/test/spec/modules/33acrossBidAdapter_spec.js b/test/spec/modules/33acrossBidAdapter_spec.js index 110a5655f40..93c7a742bfa 100644 --- a/test/spec/modules/33acrossBidAdapter_spec.js +++ b/test/spec/modules/33acrossBidAdapter_spec.js @@ -257,7 +257,7 @@ describe('33acrossBidAdapter:', function () { return Object.assign(fm, { ext: { ttx: { - bidfloors: [ floors[i] ] + bidfloors: [floors[i]] } } }) @@ -482,7 +482,7 @@ describe('33acrossBidAdapter:', function () { } this.buildBidderRequest = (bidRequests, additionalProps) => { - const [ bidRequest ] = bidRequests; + const [bidRequest] = bidRequests; return utils.mergeDeep({ ortb2: utils.mergeDeep({ @@ -775,7 +775,7 @@ describe('33acrossBidAdapter:', function () { it('returns false', function() { const bidRequests = ( new BidRequestsBuilder() - .withVideo({context: 'instream', protocols: [1, 2], mimes: ['foo', 'bar']}) + .withVideo({ context: 'instream', protocols: [1, 2], mimes: ['foo', 'bar'] }) .build() ); @@ -797,7 +797,7 @@ describe('33acrossBidAdapter:', function () { it('returns true', function() { const bidRequests = ( new BidRequestsBuilder() - .withVideo({context: 'outstream', protocols: [1, 2], mimes: ['foo', 'bar']}) + .withVideo({ context: 'outstream', protocols: [1, 2], mimes: ['foo', 'bar'] }) .build() ); @@ -833,7 +833,7 @@ describe('33acrossBidAdapter:', function () { const bidRequests = this.buildBannerBidRequests(); // Bids have the default zone ID configured const bidderRequest = this.buildBidderRequest(bidRequests); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }) @@ -864,7 +864,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -876,7 +876,7 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withViewability({amount: 100}) + .withViewability({ amount: 100 }) .build() ); @@ -884,7 +884,7 @@ describe('33acrossBidAdapter:', function () { const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -896,7 +896,7 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withViewability({amount: 0}) + .withViewability({ amount: 0 }) .build() ); const bidRequests = this.buildBannerBidRequests(); @@ -904,7 +904,7 @@ describe('33acrossBidAdapter:', function () { Object.assign(this.element, { x: -300, y: 0, width: 207, height: 320 }); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -916,7 +916,7 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withViewability({amount: 75}) + .withViewability({ amount: 75 }) .build() ) const bidRequests = this.buildBannerBidRequests(); @@ -924,7 +924,7 @@ describe('33acrossBidAdapter:', function () { Object.assign(this.element, { width: 800, height: 800 }); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -937,7 +937,7 @@ describe('33acrossBidAdapter:', function () { .withBanner() .withProduct() .withSizes([{ w: 800, h: 2400 }]) - .withViewability({amount: 25}) + .withViewability({ amount: 25 }) .build() ); const bidRequests = this.buildBannerBidRequests(); @@ -946,7 +946,7 @@ describe('33acrossBidAdapter:', function () { Object.assign(this.element, { width: 0, height: 0 }); bidRequests[0].mediaTypes.banner.sizes = [[800, 2400]]; - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -958,7 +958,7 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withViewability({amount: spec.NON_MEASURABLE}) + .withViewability({ amount: spec.NON_MEASURABLE }) .build() ); const bidRequests = this.buildBannerBidRequests(); @@ -971,7 +971,7 @@ describe('33acrossBidAdapter:', function () { this.sandbox.stub(utils, 'getWindowTop').returns({}); this.sandbox.stub(utils, 'getWindowSelf').returns(this.win); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -1014,7 +1014,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -1064,7 +1064,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -1077,7 +1077,7 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withViewability({amount: 0}) + .withViewability({ amount: 0 }) .build() ); const bidRequests = this.buildBannerBidRequests(); @@ -1090,7 +1090,7 @@ describe('33acrossBidAdapter:', function () { this.sandbox.stub(utils, 'getWindowTop').returns(this.win); resetWinDimensions(); - const [ buildRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [buildRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(buildRequest, serverRequest); }); @@ -1118,7 +1118,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1150,7 +1150,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1166,7 +1166,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1187,7 +1187,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1211,7 +1211,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1239,7 +1239,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1255,7 +1255,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1276,7 +1276,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1303,7 +1303,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1330,7 +1330,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1355,7 +1355,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1383,7 +1383,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1407,7 +1407,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1429,7 +1429,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1460,7 +1460,7 @@ describe('33acrossBidAdapter:', function () { }; }); - const [ builtServerRequest ] = spec.buildRequests(bidRequestsWithGpid, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequestsWithGpid, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1479,7 +1479,7 @@ describe('33acrossBidAdapter:', function () { refererInfo: {} }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1533,7 +1533,7 @@ describe('33acrossBidAdapter:', function () { } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1551,7 +1551,7 @@ describe('33acrossBidAdapter:', function () { const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1567,7 +1567,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1587,7 +1587,7 @@ describe('33acrossBidAdapter:', function () { bidRequests[0].getFloor = () => ({}); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1599,13 +1599,13 @@ describe('33acrossBidAdapter:', function () { new TtxRequestBuilder() .withBanner() .withProduct() - .withFormatFloors('banner', [ 1.0, 0.10 ]) + .withFormatFloors('banner', [1.0, 0.10]) .build() ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - bidRequests[0].getFloor = ({size, currency, mediaType}) => { + bidRequests[0].getFloor = ({ size, currency, mediaType }) => { const floor = (size[0] === 300 && size[1] === 250) ? 1.0 : 0.10 return ( { @@ -1615,7 +1615,7 @@ describe('33acrossBidAdapter:', function () { ); }; - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1626,7 +1626,7 @@ describe('33acrossBidAdapter:', function () { context('and context is instream', function() { it('builds instream request with default params', function() { const bidRequests = new BidRequestsBuilder() - .withVideo({context: 'instream'}) + .withVideo({ context: 'instream' }) .build(); const ttxRequest = new TtxRequestBuilder() .withVideo() @@ -1636,7 +1636,7 @@ describe('33acrossBidAdapter:', function () { const serverRequest = this.buildServerRequest(ttxRequest); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1669,7 +1669,7 @@ describe('33acrossBidAdapter:', function () { }; const bidRequests = ( new BidRequestsBuilder() - .withVideo({context: 'instream', ...allowedParams}) + .withVideo({ context: 'instream', ...allowedParams }) .build() ); const ttxRequest = new TtxRequestBuilder() @@ -1678,7 +1678,7 @@ describe('33acrossBidAdapter:', function () { .build(); const serverRequest = this.buildServerRequest(ttxRequest); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1701,7 +1701,7 @@ describe('33acrossBidAdapter:', function () { const serverRequest = this.buildServerRequest(ttxRequest); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1719,12 +1719,12 @@ describe('33acrossBidAdapter:', function () { .build(); const serverRequest = this.buildServerRequest( new TtxRequestBuilder() - .withVideo({plcmt: 3, playbackmethod: [2]}) + .withVideo({ plcmt: 3, playbackmethod: [2] }) .withProduct('siab') .build() ); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1741,7 +1741,7 @@ describe('33acrossBidAdapter:', function () { ); const bidRequests = this.buildBannerBidRequests(); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1759,7 +1759,7 @@ describe('33acrossBidAdapter:', function () { .build() ); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1771,7 +1771,7 @@ describe('33acrossBidAdapter:', function () { const bidRequests = ( new BidRequestsBuilder() .withBanner() - .withVideo({context: 'outstream'}) + .withVideo({ context: 'outstream' }) .build() ); const serverRequest = this.buildServerRequest( @@ -1782,7 +1782,7 @@ describe('33acrossBidAdapter:', function () { .build() ); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1792,7 +1792,7 @@ describe('33acrossBidAdapter:', function () { const bidRequests = ( new BidRequestsBuilder() .withBanner() - .withVideo({context: 'instream', plcmt: 2}) + .withVideo({ context: 'instream', plcmt: 2 }) .build() ); @@ -1803,7 +1803,7 @@ describe('33acrossBidAdapter:', function () { .build(); const serverRequest = this.buildServerRequest(ttxRequest); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1815,7 +1815,7 @@ describe('33acrossBidAdapter:', function () { it('does not set any bidfloors in video', function() { const bidRequests = ( new BidRequestsBuilder() - .withVideo({context: 'outstream'}) + .withVideo({ context: 'outstream' }) .build() ); @@ -1828,7 +1828,7 @@ describe('33acrossBidAdapter:', function () { .build() ); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1838,11 +1838,11 @@ describe('33acrossBidAdapter:', function () { it('sets bidfloors in video', function() { const bidRequests = ( new BidRequestsBuilder() - .withVideo({context: 'outstream'}) + .withVideo({ context: 'outstream' }) .build() ); - bidRequests[0].getFloor = ({size, currency, mediaType}) => { + bidRequests[0].getFloor = ({ size, currency, mediaType }) => { const floor = (mediaType === 'video') ? 1.0 : 0.10 return ( { @@ -1855,11 +1855,11 @@ describe('33acrossBidAdapter:', function () { const ttxRequest = new TtxRequestBuilder() .withVideo() .withProduct() - .withFloors('video', [ 1.0 ]) + .withFloors('video', [1.0]) .build(); const serverRequest = this.buildServerRequest(ttxRequest); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1910,7 +1910,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1937,7 +1937,7 @@ describe('33acrossBidAdapter:', function () { } } }); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -1979,7 +1979,7 @@ describe('33acrossBidAdapter:', function () { .build() ); const bidderRequest = this.buildBidderRequest(bidRequests); - const [ builtServerRequest ] = spec.buildRequests(bidRequests, bidderRequest); + const [builtServerRequest] = spec.buildRequests(bidRequests, bidderRequest); validateBuiltServerRequest(builtServerRequest, serverRequest); }); @@ -2012,7 +2012,7 @@ describe('33acrossBidAdapter:', function () { } }) .withBanner() - .withVideo({context: 'outstream'}) + .withVideo({ context: 'outstream' }) .build(); const req1 = new TtxRequestBuilder() @@ -2066,7 +2066,7 @@ describe('33acrossBidAdapter:', function () { } }) .withBanner() - .withVideo({context: 'outstream'}) + .withVideo({ context: 'outstream' }) .build(); const req1 = new TtxRequestBuilder() @@ -2457,7 +2457,7 @@ describe('33acrossBidAdapter:', function () { it('returns sync urls with undefined consent string as param and gdpr=1', function() { spec.buildRequests(this.bidRequests); - const syncResults = spec.getUserSyncs(this.syncOptions, {}, {gdprApplies: true}); + const syncResults = spec.getUserSyncs(this.syncOptions, {}, { gdprApplies: true }); const expectedSyncs = [ { type: 'iframe', @@ -2477,7 +2477,7 @@ describe('33acrossBidAdapter:', function () { it('returns sync urls with gdpr_consent=consent string as param and gdpr=1', function() { spec.buildRequests(this.bidRequests); - const syncResults = spec.getUserSyncs(this.syncOptions, {}, {gdprApplies: true, consentString: 'consent123A'}); + const syncResults = spec.getUserSyncs(this.syncOptions, {}, { gdprApplies: true, consentString: 'consent123A' }); const expectedSyncs = [ { type: 'iframe', @@ -2497,7 +2497,7 @@ describe('33acrossBidAdapter:', function () { it('returns sync urls with undefined consent string as param and gdpr=0', function() { spec.buildRequests(this.bidRequests); - const syncResults = spec.getUserSyncs(this.syncOptions, {}, {gdprApplies: false}); + const syncResults = spec.getUserSyncs(this.syncOptions, {}, { gdprApplies: false }); const expectedSyncs = [ { type: 'iframe', @@ -2516,7 +2516,7 @@ describe('33acrossBidAdapter:', function () { it('returns sync urls with only consent string as param', function() { spec.buildRequests(this.bidRequests); - const syncResults = spec.getUserSyncs(this.syncOptions, {}, {consentString: 'consent123A'}); + const syncResults = spec.getUserSyncs(this.syncOptions, {}, { consentString: 'consent123A' }); const expectedSyncs = [ { type: 'iframe', @@ -2535,7 +2535,7 @@ describe('33acrossBidAdapter:', function () { it('returns sync urls with consent string as param and gdpr=0', function() { spec.buildRequests(this.bidRequests); - const syncResults = spec.getUserSyncs(this.syncOptions, {}, {gdprApplies: false, consentString: 'consent123A'}); + const syncResults = spec.getUserSyncs(this.syncOptions, {}, { gdprApplies: false, consentString: 'consent123A' }); const expectedSyncs = [ { type: 'iframe', diff --git a/test/spec/modules/33acrossIdSystem_spec.js b/test/spec/modules/33acrossIdSystem_spec.js index 3cf5995bb17..7c861c0723f 100644 --- a/test/spec/modules/33acrossIdSystem_spec.js +++ b/test/spec/modules/33acrossIdSystem_spec.js @@ -3,9 +3,9 @@ import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; import { uspDataHandler, coppaDataHandler, gppDataHandler } from 'src/adapterManager.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; -import {attachIdSystem} from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; describe('33acrossIdSystem', () => { describe('name', () => { @@ -86,7 +86,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -134,7 +134,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } }); @@ -172,7 +172,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -208,7 +208,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'cookie', 'html5' ], + enabledStorageTypes: ['cookie', 'html5'], storage: {} }); @@ -250,7 +250,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -260,6 +260,7 @@ describe('33acrossIdSystem', () => { const removeDataFromLocalStorage = sinon.stub(storage, 'removeDataFromLocalStorage'); const setCookie = sinon.stub(storage, 'setCookie'); + const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); sinon.stub(domainUtils, 'domainOverride').returns('foo.com'); request.respond(200, { @@ -277,6 +278,7 @@ describe('33acrossIdSystem', () => { removeDataFromLocalStorage.restore(); setCookie.restore(); + cookiesAreEnabled.restore(); domainUtils.domainOverride.restore(); }); }); @@ -293,7 +295,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } }); @@ -331,7 +333,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -367,7 +369,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'cookie', 'html5' ], + enabledStorageTypes: ['cookie', 'html5'], storage: {} }); @@ -409,7 +411,7 @@ describe('33acrossIdSystem', () => { pid: '12345', ...opts }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -419,6 +421,7 @@ describe('33acrossIdSystem', () => { const removeDataFromLocalStorage = sinon.stub(storage, 'removeDataFromLocalStorage'); const setCookie = sinon.stub(storage, 'setCookie'); + const cookiesAreEnabled = sinon.stub(storage, 'cookiesAreEnabled').returns(true); sinon.stub(domainUtils, 'domainOverride').returns('foo.com'); request.respond(200, { @@ -436,6 +439,7 @@ describe('33acrossIdSystem', () => { removeDataFromLocalStorage.restore(); setCookie.restore(); + cookiesAreEnabled.restore(); domainUtils.domainOverride.restore(); }); }); @@ -452,7 +456,7 @@ describe('33acrossIdSystem', () => { pid: '12345', storeFpid: false }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } @@ -490,7 +494,7 @@ describe('33acrossIdSystem', () => { pid: '12345', storeFpid: false }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -528,7 +532,7 @@ describe('33acrossIdSystem', () => { pid: '12345', storeTpid: false }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } @@ -564,7 +568,7 @@ describe('33acrossIdSystem', () => { pid: '12345', storeTpid: false }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -600,7 +604,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -642,7 +646,7 @@ describe('33acrossIdSystem', () => { pid: '12345' } }, { - gdpr: {gdprApplies: true} + gdpr: { gdprApplies: true } }); expect(logWarnSpy.calledOnceWithExactly('33acrossId: Submodule cannot be used where GDPR applies')).to.be.true; @@ -660,7 +664,7 @@ describe('33acrossIdSystem', () => { pid: '12345' } }, { - gdpr: {gdprApplies: false} + gdpr: { gdprApplies: false } }); callback(completeCallback); @@ -845,7 +849,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -870,7 +874,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: {} }); @@ -912,7 +916,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -937,7 +941,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: {} }); @@ -980,7 +984,7 @@ describe('33acrossIdSystem', () => { pid: '12345', hem: '33acrossIdHmValue+' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -1007,7 +1011,7 @@ describe('33acrossIdSystem', () => { pid: '12345', hem: '33acrossIdHmValue+' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -1043,7 +1047,7 @@ describe('33acrossIdSystem', () => { pid: '12345', hem: '33acrossIdHmValue+' }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } }); @@ -1094,7 +1098,7 @@ describe('33acrossIdSystem', () => { pid: '12345' // No hashed email via config option. }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -1120,7 +1124,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -1155,7 +1159,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: { expires: 30 } }); @@ -1192,7 +1196,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); @@ -1217,7 +1221,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'cookie' ], + enabledStorageTypes: ['cookie'], storage: {} }); @@ -1466,7 +1470,7 @@ describe('33acrossIdSystem', () => { params: { pid: '12345' }, - enabledStorageTypes: [ 'html5' ], + enabledStorageTypes: ['html5'], storage: {} }); diff --git a/test/spec/modules/360playvidBidAdapter_spec.js b/test/spec/modules/360playvidBidAdapter_spec.js index 393afbf4545..7718c0c2eca 100644 --- a/test/spec/modules/360playvidBidAdapter_spec.js +++ b/test/spec/modules/360playvidBidAdapter_spec.js @@ -483,7 +483,7 @@ describe('360PlayVidBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -492,9 +492,7 @@ describe('360PlayVidBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookie.360playvid.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -503,7 +501,7 @@ describe('360PlayVidBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookie.360playvid.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/51DegreesRtdProvider_spec.js b/test/spec/modules/51DegreesRtdProvider_spec.js index 4993f9097f6..337f0a78188 100644 --- a/test/spec/modules/51DegreesRtdProvider_spec.js +++ b/test/spec/modules/51DegreesRtdProvider_spec.js @@ -8,7 +8,7 @@ import { getBidRequestData, fiftyOneDegreesSubmodule, } from 'modules/51DegreesRtdProvider'; -import {mergeDeep} from '../../../src/utils.js'; +import { mergeDeep } from '../../../src/utils.js'; const inject51DegreesMeta = () => { const meta = document.createElement('meta'); @@ -80,7 +80,7 @@ describe('51DegreesRtdProvider', function() { describe('extractConfig', function() { it('returns the resourceKey from the moduleConfig', function() { const reqBidsConfigObj = {}; - const moduleConfig = {params: {resourceKey: 'TEST_RESOURCE_KEY'}}; + const moduleConfig = { params: { resourceKey: 'TEST_RESOURCE_KEY' } }; expect(extractConfig(moduleConfig, reqBidsConfigObj)).to.deep.equal({ resourceKey: 'TEST_RESOURCE_KEY', onPremiseJSUrl: undefined, @@ -89,7 +89,7 @@ describe('51DegreesRtdProvider', function() { it('returns the onPremiseJSUrl from the moduleConfig', function() { const reqBidsConfigObj = {}; - const moduleConfig = {params: {onPremiseJSUrl: 'https://example.com/51Degrees.core.js'}}; + const moduleConfig = { params: { onPremiseJSUrl: 'https://example.com/51Degrees.core.js' } }; expect(extractConfig(moduleConfig, reqBidsConfigObj)).to.deep.equal({ onPremiseJSUrl: 'https://example.com/51Degrees.core.js', resourceKey: undefined, @@ -98,30 +98,34 @@ describe('51DegreesRtdProvider', function() { it('throws an error if neither resourceKey nor onPremiseJSUrl is provided', function() { const reqBidsConfigObj = {}; - const moduleConfig = {params: {}}; + const moduleConfig = { params: {} }; expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw(); }); it('throws an error if both resourceKey and onPremiseJSUrl are provided', function() { const reqBidsConfigObj = {}; - const moduleConfig = {params: { - resourceKey: 'TEST_RESOURCE_KEY', - onPremiseJSUrl: 'https://example.com/51Degrees.core.js', - }}; + const moduleConfig = { + params: { + resourceKey: 'TEST_RESOURCE_KEY', + onPremiseJSUrl: 'https://example.com/51Degrees.core.js', + } + }; expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw(); }); it('throws an error if the resourceKey is equal to "" from example', function() { const reqBidsConfigObj = {}; - const moduleConfig = {params: {resourceKey: ''}}; + const moduleConfig = { params: { resourceKey: '' } }; expect(() => extractConfig(moduleConfig, reqBidsConfigObj)).to.throw(); }); it('sets the resourceKey to undefined if it was set to "0"', function() { - const moduleConfig = {params: { - resourceKey: '0', - onPremiseJSUrl: 'https://example.com/51Degrees.core.js', - }}; + const moduleConfig = { + params: { + resourceKey: '0', + onPremiseJSUrl: 'https://example.com/51Degrees.core.js', + } + }; expect(extractConfig(moduleConfig, {})).to.deep.equal({ resourceKey: undefined, onPremiseJSUrl: 'https://example.com/51Degrees.core.js', @@ -129,10 +133,12 @@ describe('51DegreesRtdProvider', function() { }); it('sets the onPremiseJSUrl to undefined if it was set to "0"', function() { - const moduleConfig = {params: { - resourceKey: 'TEST_RESOURCE_KEY', - onPremiseJSUrl: '0', - }}; + const moduleConfig = { + params: { + resourceKey: 'TEST_RESOURCE_KEY', + onPremiseJSUrl: '0', + } + }; expect(extractConfig(moduleConfig, {})).to.deep.equal({ resourceKey: 'TEST_RESOURCE_KEY', onPremiseJSUrl: undefined, @@ -141,10 +147,10 @@ describe('51DegreesRtdProvider', function() { it('throws an error if the onPremiseJSUrl is not a valid URL', function() { expect(() => extractConfig({ - params: {onPremiseJSUrl: 'invalid URL'} + params: { onPremiseJSUrl: 'invalid URL' } }, {})).to.throw(); expect(() => extractConfig({ - params: {onPremiseJSUrl: 'www.example.com/51Degrees.core.js'} + params: { onPremiseJSUrl: 'www.example.com/51Degrees.core.js' } }, {})).to.throw(); }); @@ -158,7 +164,7 @@ describe('51DegreesRtdProvider', function() { VALID_URLS.forEach(url => { expect(() => extractConfig({ - params: {onPremiseJSUrl: url} + params: { onPremiseJSUrl: url } }, {})).to.not.throw(); }); }); @@ -209,7 +215,7 @@ describe('51DegreesRtdProvider', function() { }; it('returns the cloud URL if the resourceKey is provided', function() { - const config = {resourceKey: 'TEST_RESOURCE_KEY'}; + const config = { resourceKey: 'TEST_RESOURCE_KEY' }; expect(get51DegreesJSURL(config, mockWindow)).to.equal( 'https://cloud.51degrees.com/api/v4/TEST_RESOURCE_KEY.js?' + `51D_ScreenPixelsHeight=${mockWindow.screen.height}&` + @@ -219,7 +225,7 @@ describe('51DegreesRtdProvider', function() { }); it('returns the on-premise URL if the onPremiseJSUrl is provided', function () { - const config = {onPremiseJSUrl: 'https://example.com/51Degrees.core.js'}; + const config = { onPremiseJSUrl: 'https://example.com/51Degrees.core.js' }; expect(get51DegreesJSURL(config, mockWindow)).to.equal( `https://example.com/51Degrees.core.js?` + `51D_ScreenPixelsHeight=${mockWindow.screen.height}&` + @@ -229,7 +235,7 @@ describe('51DegreesRtdProvider', function() { }); it('doesn\'t override static query string parameters', function () { - const config = {onPremiseJSUrl: 'https://example.com/51Degrees.core.js?test=1'}; + const config = { onPremiseJSUrl: 'https://example.com/51Degrees.core.js?test=1' }; expect(get51DegreesJSURL(config, mockWindow)).to.equal( `https://example.com/51Degrees.core.js?test=1&` + `51D_ScreenPixelsHeight=${mockWindow.screen.height}&` + @@ -270,7 +276,7 @@ describe('51DegreesRtdProvider', function() { delete mockWindow.screen; delete mockWindow.devicePixelRatio; - const config = {onPremiseJSUrl: 'https://example.com/51Degrees.core.js'}; + const config = { onPremiseJSUrl: 'https://example.com/51Degrees.core.js' }; expect(get51DegreesJSURL(config, mockWindow)).to.equal('https://example.com/51Degrees.core.js'); expect(get51DegreesJSURL(config, window)).to.not.equal('https://example.com/51Degrees.core.js'); }); @@ -315,7 +321,7 @@ describe('51DegreesRtdProvider', function() { it('sets value of ORTB2 key if it is not empty', function() { const data = {}; deepSetNotEmptyValue(data, 'TEST_ORTB2_KEY', 'TEST_ORTB2_VALUE'); - expect(data).to.deep.equal({TEST_ORTB2_KEY: 'TEST_ORTB2_VALUE'}); + expect(data).to.deep.equal({ TEST_ORTB2_KEY: 'TEST_ORTB2_VALUE' }); deepSetNotEmptyValue(data, 'test2.TEST_ORTB2_KEY_2', 'TEST_ORTB2_VALUE_2'); expect(data).to.deep.equal({ TEST_ORTB2_KEY: 'TEST_ORTB2_VALUE', @@ -365,27 +371,27 @@ describe('51DegreesRtdProvider', function() { }); it('does not set the deviceid if it is not provided', function() { - const device = {...fiftyOneDegreesDevice}; + const device = { ...fiftyOneDegreesDevice }; delete device.deviceid; expect(convert51DegreesDeviceToOrtb2(device).device.ext).to.not.have.any.keys('fiftyonedegrees_deviceId'); expect(convert51DegreesDeviceToOrtb2(device).device.ext.fod).to.not.have.any.keys('deviceId'); }); it('sets the model to hardwarename if hardwaremodel is not provided', function() { - const device = {...fiftyOneDegreesDevice}; + const device = { ...fiftyOneDegreesDevice }; delete device.hardwaremodel; - expect(convert51DegreesDeviceToOrtb2(device).device).to.deep.include({model: 'Macintosh'}); + expect(convert51DegreesDeviceToOrtb2(device).device).to.deep.include({ model: 'Macintosh' }); }); it('does not set the model if hardwarename is empty', function() { - const device = {...fiftyOneDegreesDevice}; + const device = { ...fiftyOneDegreesDevice }; delete device.hardwaremodel; device.hardwarename = []; expect(convert51DegreesDeviceToOrtb2(device).device).to.not.have.any.keys('model'); }); it('does not set the ppi if screeninchesheight is not provided', function() { - const device = {...fiftyOneDegreesDevice}; + const device = { ...fiftyOneDegreesDevice }; delete device.screeninchesheight; expect(convert51DegreesDeviceToOrtb2(device).device).to.not.have.any.keys('ppi'); }); @@ -454,14 +460,14 @@ describe('51DegreesRtdProvider', function() { it('calls the callback even if submodule fails (wrong config)', function() { const callback = sinon.spy(); - const moduleConfig = {params: {}}; + const moduleConfig = { params: {} }; getBidRequestData(reqBidsConfigObj, callback, moduleConfig, {}); expect(callback.calledOnce).to.be.true; }); it('calls the callback even if submodule fails (on-premise, non-working URL)', async function() { const callback = sinon.spy(); - const moduleConfig = {params: {onPremiseJSUrl: 'http://localhost:12345/test/51Degrees.core.js'}}; + const moduleConfig = { params: { onPremiseJSUrl: 'http://localhost:12345/test/51Degrees.core.js' } }; getBidRequestData(reqBidsConfigObj, callback, moduleConfig, {}); await new Promise(resolve => setTimeout(resolve, 100)); @@ -470,7 +476,7 @@ describe('51DegreesRtdProvider', function() { it('calls the callback even if submodule fails (invalid resource key)', async function() { const callback = sinon.spy(); - const moduleConfig = {params: {resourceKey: 'INVALID_RESOURCE_KEY'}}; + const moduleConfig = { params: { resourceKey: 'INVALID_RESOURCE_KEY' } }; getBidRequestData(reqBidsConfigObj, callback, moduleConfig, {}); await new Promise(resolve => setTimeout(resolve, 100)); @@ -480,7 +486,7 @@ describe('51DegreesRtdProvider', function() { it('works with Delegate-CH meta tag', async function() { inject51DegreesMeta(); const callback = sinon.spy(); - const moduleConfig = {params: {resourceKey: 'INVALID_RESOURCE_KEY'}}; + const moduleConfig = { params: { resourceKey: 'INVALID_RESOURCE_KEY' } }; getBidRequestData(reqBidsConfigObj, callback, moduleConfig, {}); await new Promise(resolve => setTimeout(resolve, 100)); expect(callback.calledOnce).to.be.true; @@ -488,7 +494,7 @@ describe('51DegreesRtdProvider', function() { it('has the correct ORTB2 data', async function() { const callback = sinon.spy(); - const moduleConfig = {params: {resourceKey: 'INVALID_RESOURCE_KEY'}}; + const moduleConfig = { params: { resourceKey: 'INVALID_RESOURCE_KEY' } }; getBidRequestData(reqBidsConfigObj, callback, moduleConfig, {}); await new Promise(resolve => setTimeout(resolve, 100)); expect(callback.calledOnce).to.be.true; diff --git a/test/spec/modules/AsteriobidPbmAnalyticsAdapter_spec.js b/test/spec/modules/AsteriobidPbmAnalyticsAdapter_spec.js index d94368eeeb6..e148042ce09 100644 --- a/test/spec/modules/AsteriobidPbmAnalyticsAdapter_spec.js +++ b/test/spec/modules/AsteriobidPbmAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import prebidmanagerAnalytics, {storage} from 'modules/AsteriobidPbmAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; +import prebidmanagerAnalytics, { storage } from 'modules/AsteriobidPbmAnalyticsAdapter.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; import * as utils from 'src/utils.js'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expectEvents } from '../../helpers/analytics.js'; import { EVENTS } from 'src/constants.js'; const events = require('src/events'); diff --git a/test/spec/modules/ViouslyBidAdapter_spec.js b/test/spec/modules/ViouslyBidAdapter_spec.js index 16f32e3d6ab..c7fbf9a4bd6 100644 --- a/test/spec/modules/ViouslyBidAdapter_spec.js +++ b/test/spec/modules/ViouslyBidAdapter_spec.js @@ -1,10 +1,10 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { deepClone, mergeDeep } from 'src/utils'; import { BANNER, VIDEO } from 'src/mediaTypes'; import { createEidsArray } from 'modules/userId/eids.js'; -import {spec as adapter} from 'modules/viouslyBidAdapter'; +import { spec as adapter } from 'modules/viouslyBidAdapter'; import sinon from 'sinon'; import { config } from 'src/config.js'; diff --git a/test/spec/modules/a1MediaBidAdapter_spec.js b/test/spec/modules/a1MediaBidAdapter_spec.js index 3c5fa14c61d..361644701cb 100644 --- a/test/spec/modules/a1MediaBidAdapter_spec.js +++ b/test/spec/modules/a1MediaBidAdapter_spec.js @@ -6,7 +6,7 @@ import 'modules/priceFloors.js'; import { replaceAuctionPrice } from '../../../src/utils.js'; const ortbBlockParams = { - battr: [ 13 ], + battr: [13], bcat: ['IAB1-1'] }; const getBidderRequest = (isMulti = false) => { @@ -22,7 +22,7 @@ const getBidderRequest = (isMulti = false) => { mediaTypes: { banner: { sizes: [ - [ 320, 100 ], + [320, 100], ] }, ...(isMulti && { @@ -32,7 +32,8 @@ const getBidderRequest = (isMulti = false) => { native: { title: { required: true, - }} + } + } }) }, ...(isMulti && { diff --git a/test/spec/modules/a1MediaRtdProvider_spec.js b/test/spec/modules/a1MediaRtdProvider_spec.js index f313062b192..abadb4fd7cc 100644 --- a/test/spec/modules/a1MediaRtdProvider_spec.js +++ b/test/spec/modules/a1MediaRtdProvider_spec.js @@ -30,7 +30,7 @@ const a1TestOrtbObj = { ext: { segtax: 900 }, - segment: [{id: 'test'}] + segment: [{ id: 'test' }] } ], ext: { diff --git a/test/spec/modules/aaxBlockmeter_spec.js b/test/spec/modules/aaxBlockmeter_spec.js index 88b750274ee..3b1997901b5 100644 --- a/test/spec/modules/aaxBlockmeter_spec.js +++ b/test/spec/modules/aaxBlockmeter_spec.js @@ -1,6 +1,6 @@ -import {aaxBlockmeterRtdModule} from '../../../modules/aaxBlockmeterRtdProvider.js'; +import { aaxBlockmeterRtdModule } from '../../../modules/aaxBlockmeterRtdProvider.js'; import * as sinon from 'sinon'; -import {assert} from 'chai'; +import { assert } from 'chai'; let sandbox; let getTargetingDataSpy; @@ -31,11 +31,11 @@ describe('aaxBlockmeter realtime module', function () { }); it('init should return false when config.params id is empty', function () { - assert.equal(aaxBlockmeterRtdModule.init({params: {}}), false); + assert.equal(aaxBlockmeterRtdModule.init({ params: {} }), false); }); it('init should return true when config.params.pub is not string', function () { - assert.equal(aaxBlockmeterRtdModule.init({params: {pub: 12345}}), false); + assert.equal(aaxBlockmeterRtdModule.init({ params: { pub: 12345 } }), false); }); it('init should return true when config.params.pub id is passed and is string typed', function () { @@ -46,8 +46,8 @@ describe('aaxBlockmeter realtime module', function () { it('should return ad unit codes when ad units are present', function () { const codes = ['code1', 'code2']; assert.deepEqual(aaxBlockmeterRtdModule.getTargetingData(codes), { - code1: {'atk': 'code1'}, - code2: {'atk': 'code2'}, + code1: { 'atk': 'code1' }, + code2: { 'atk': 'code2' }, }); }); diff --git a/test/spec/modules/ablidaBidAdapter_spec.js b/test/spec/modules/ablidaBidAdapter_spec.js index f5e633369aa..da209859e2f 100644 --- a/test/spec/modules/ablidaBidAdapter_spec.js +++ b/test/spec/modules/ablidaBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/ablidaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/ablidaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; const ENDPOINT_URL = 'https://bidder.ablida.net/prebid'; @@ -17,7 +17,7 @@ describe('ablidaBidAdapter', function () { bidderRequestsCount: 1, bidderWinsCount: 0, bidId: '1234asdf1234', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { placementId: 123 }, @@ -42,7 +42,7 @@ describe('ablidaBidAdapter', function () { bidderRequestId: '14d2939272a26a', bidderRequestsCount: 1, bidderWinsCount: 0, - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { placementId: 123 }, @@ -81,7 +81,7 @@ describe('ablidaBidAdapter', function () { device: 'desktop', gdprConsent: undefined, jaySupported: true, - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, placementId: 'testPlacementId', width: 300, height: 200, diff --git a/test/spec/modules/aceexBidAdapter_spec.js b/test/spec/modules/aceexBidAdapter_spec.js new file mode 100644 index 00000000000..dd83280f78e --- /dev/null +++ b/test/spec/modules/aceexBidAdapter_spec.js @@ -0,0 +1,248 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/aceexBidAdapter.js'; + +describe('aceexBidAdapter', function () { + const makeBidderRequest = (ortb2 = {}) => ({ + bidderCode: 'aceex', + auctionId: 'auction-1', + bidderRequestId: 'br-1', + ortb2 + }); + + const makeBid = (overrides = {}) => ({ + bidId: overrides.bidId || 'bid-1', + bidder: 'aceex', + params: { + publisherId: 'pub-1', + trafficType: 'banner', + internalKey: 'ik-1', + bidfloor: 0.1, + ...overrides.params, + }, + mediaTypes: overrides.mediaTypes, + sizes: overrides.sizes, + ...overrides, + }); + + describe('isBidRequestValid', function () { + it('should return true when bidId, params.publisherId and params.trafficType are present', function () { + const bid = makeBid({ + bidId: 'bid-123', + params: { publisherId: 'pub-123', trafficType: 'banner' } + }); + + expect(spec.isBidRequestValid(bid)).to.equal(true); + }); + + it('should return false when bidId is missing', function () { + const bid = makeBid({ bidId: undefined }); + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when params.publisherId is missing', function () { + const bid = makeBid({ params: { trafficType: 'banner' } }); + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + + it('should return false when params.trafficType is missing', function () { + const bid = makeBid({ params: { publisherId: 'pub-1' } }); + expect(spec.isBidRequestValid(bid)).to.equal(false); + }); + }); + + describe('buildRequests', function () { + it('should build a single request object', function () { + const bidderRequest = makeBidderRequest(); + const validBidRequests = [makeBid({ bidId: 'bid-1' })]; + + const req = spec.buildRequests(validBidRequests, bidderRequest); + + expect(req).to.be.an('object'); + + expect(req).to.have.property('data'); + }); + + it('should map ortb2 fields into request.data (cat, keywords, badv, wseat, bseat)', function () { + const bidderRequest = makeBidderRequest({ + cat: ['IAB1', 'IAB1-1'], + keywords: { key1: ['v1', 'v2'] }, + badv: ['bad.com'], + wseat: ['seat1'], + bseat: ['seat2'], + }); + + const validBidRequests = [makeBid({ bidId: 'bid-1' })]; + const req = spec.buildRequests(validBidRequests, bidderRequest); + + expect(req.data.cat).to.deep.equal(['IAB1', 'IAB1-1']); + expect(req.data.keywords).to.deep.equal({ key1: ['v1', 'v2'] }); + expect(req.data.badv).to.deep.equal(['bad.com']); + expect(req.data.wseat).to.deep.equal(['seat1']); + expect(req.data.bseat).to.deep.equal(['seat2']); + }); + + it('should not throw if ortb2 fields are missing', function () { + const bidderRequest = makeBidderRequest(); + const validBidRequests = [makeBid({ bidId: 'bid-1' })]; + + expect(() => spec.buildRequests(validBidRequests, bidderRequest)).to.not.throw(); + }); + }); + + describe('interpretResponse', function () { + it('should return [] when serverResponse/body is missing', function () { + expect(spec.interpretResponse(null, {})).to.deep.equal([]); + expect(spec.interpretResponse({}, {})).to.deep.equal([]); + expect(spec.interpretResponse({ body: null }, {})).to.deep.equal([]); + }); + + it('should interpret banner bid', function () { + const bidRequest = { + data: { + placements: [ + { bidId: 'resp-bid-1', adFormat: 'banner' } + ] + } + }; + + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'resp-bid-1', + price: 1.23, + crid: 'cr-1', + dealid: 'deal-1', + h: 250, + w: 300, + adm: '
price=1.23
', + nurl: 'https://win.example.com?c=1.23', + adomain: ['test.com'] + }] + }] + } + }; + + const out = spec.interpretResponse(serverResponse, bidRequest); + expect(out).to.have.lengthOf(1); + + const b = out[0]; + expect(b.requestId).to.equal('resp-bid-1'); + expect(b.cpm).to.equal(1.23); + expect(b.mediaType).to.equal('banner'); + expect(b.width).to.equal(300); + expect(b.height).to.equal(250); + expect(b.ad).to.include('1.23'); + expect(b.meta.advertiserDomains[0]).to.equal('test.com'); + }); + + it('should interpret video bid as vastXml', function () { + const bidRequest = { + data: { + placements: [ + { bidId: 'resp-bid-2', adFormat: 'video' } + ] + } + }; + + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'resp-bid-2', + price: 5, + crid: 'cr-v', + dealid: 'deal-v', + h: 360, + w: 640, + adm: '', + nurl: 'https://win.example.com?c=5', + adomain: ['test.com'] + }] + }] + } + }; + + const out = spec.interpretResponse(serverResponse, bidRequest); + expect(out).to.have.lengthOf(1); + + const b = out[0]; + expect(b.mediaType).to.equal('video'); + expect(b.vastXml).to.equal(''); + expect(b.ad).to.equal(undefined); + }); + + it('should interpret native bid into native.ortb', function () { + const bidRequest = { + data: { + placements: [ + { bidId: 'resp-bid-3', adFormat: 'native' } + ] + } + }; + + const nativeAdm = JSON.stringify({ + native: { + assets: [{ id: 1, title: { text: 'Hello' } }], + imptrackers: ['https://imp.example.com/1'], + link: { url: 'https://click.example.com' } + } + }); + + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'resp-bid-3', + price: 2.5, + crid: 'cr-n', + dealid: 'deal-n', + h: 1, + w: 1, + adm: nativeAdm, + nurl: 'https://win.example.com?c=5', + adomain: ['test.com'] + }] + }] + } + }; + + const out = spec.interpretResponse(serverResponse, bidRequest); + expect(out).to.have.lengthOf(1); + + const b = out[0]; + expect(b.mediaType).to.equal('native'); + expect(b).to.have.property('native'); + expect(b.native).to.have.property('ortb'); + + expect(b.native.ortb.assets).to.deep.equal([{ id: 1, title: { text: 'Hello' } }]); + expect(b.native.ortb.imptrackers).to.deep.equal(['https://imp.example.com/1']); + expect(b.native.ortb.link).to.deep.equal({ url: 'https://click.example.com' }); + }); + + it('should handle multiple seatbids and multiple bids', function () { + const bidRequest = { + data: { + placements: [ + { bidId: 'b1', adFormat: 'banner' }, + { bidId: 'b2', adFormat: 'video' } + ] + } + }; + + const serverResponse = { + body: { + seatbid: [ + { bid: [{ id: 'b1', price: 1, crid: 'c1', dealid: 'd1', h: 250, w: 300, adm: '
', nurl: '', adomain: ['test.com'] }] }, + { bid: [{ id: 'b2', price: 2, crid: 'c2', dealid: 'd2', h: 360, w: 640, adm: '', nurl: '', adomain: ['test.com'] }] } + ] + } + }; + + const out = spec.interpretResponse(serverResponse, bidRequest); + expect(out).to.have.lengthOf(2); + expect(out.find(x => x.requestId === 'b1').mediaType).to.equal('banner'); + expect(out.find(x => x.requestId === 'b2').mediaType).to.equal('video'); + }); + }); +}); diff --git a/test/spec/modules/acuityadsBidAdapter_spec.js b/test/spec/modules/acuityadsBidAdapter_spec.js index e37b6913ced..f7979c969df 100644 --- a/test/spec/modules/acuityadsBidAdapter_spec.js +++ b/test/spec/modules/acuityadsBidAdapter_spec.js @@ -531,7 +531,7 @@ describe('AcuityAdsBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -540,9 +540,7 @@ describe('AcuityAdsBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.admanmedia.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -551,7 +549,7 @@ describe('AcuityAdsBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.admanmedia.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/adWMGAnalyticsAdapter_spec.js b/test/spec/modules/adWMGAnalyticsAdapter_spec.js index d766a0f8ba3..112225e8019 100644 --- a/test/spec/modules/adWMGAnalyticsAdapter_spec.js +++ b/test/spec/modules/adWMGAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ import adWMGAnalyticsAdapter from 'modules/adWMGAnalyticsAdapter.js'; import { expect } from 'chai'; import { server } from 'test/mocks/xhr.js'; -import {expectEvents} from '../../helpers/analytics.js'; -import {EVENTS} from 'src/constants.js'; +import { expectEvents } from '../../helpers/analytics.js'; +import { EVENTS } from 'src/constants.js'; const adapterManager = require('src/adapterManager').default; const events = require('src/events'); @@ -142,7 +142,7 @@ describe('adWMG Analytics', function () { }); expectEvents([ - [EVENTS.AUCTION_INIT, {timestamp, auctionId, timeout, adUnits}], + [EVENTS.AUCTION_INIT, { timestamp, auctionId, timeout, adUnits }], [EVENTS.BID_REQUESTED, {}], [EVENTS.BID_RESPONSE, bidResponse], [EVENTS.NO_BID, {}], diff --git a/test/spec/modules/adagioAnalyticsAdapter_spec.js b/test/spec/modules/adagioAnalyticsAdapter_spec.js index d77a0fb8bd6..c493ef960ec 100644 --- a/test/spec/modules/adagioAnalyticsAdapter_spec.js +++ b/test/spec/modules/adagioAnalyticsAdapter_spec.js @@ -222,7 +222,7 @@ const AUCTION_INIT_ANOTHER = { 'auctionId': AUCTION_ID, 'timestamp': 1519767010567, 'auctionStatus': 'inProgress', - 'adUnits': [ { + 'adUnits': [{ 'code': '/19968336/header-bid-tag-1', 'mediaTypes': { 'banner': { @@ -244,7 +244,7 @@ const AUCTION_INIT_ANOTHER = { } }, 'sizes': [[640, 480]], - 'bids': [ { + 'bids': [{ 'bidder': 'another', 'params': { 'publisherId': '1001' @@ -264,7 +264,7 @@ const AUCTION_INIT_ANOTHER = { 'params': { 'publisherId': '1001' }, - }, ], + },], 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014' }, { 'code': '/19968336/footer-bid-tag-1', @@ -279,12 +279,12 @@ const AUCTION_INIT_ANOTHER = { } }, 'sizes': [[640, 480]], - 'bids': [ { + 'bids': [{ 'bidder': 'another', 'params': { 'publisherId': '1001' }, - } ], + }], 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', 'ortb2Imp': { 'ext': { @@ -295,7 +295,7 @@ const AUCTION_INIT_ANOTHER = { } } }, - } ], + }], 'adUnitCodes': ['/19968336/header-bid-tag-1', '/19968336/footer-bid-tag-1'], 'bidderRequests': [ { @@ -462,7 +462,7 @@ const AUCTION_INIT_ANOTHER = { 'bidderCode': 'adagio', 'auctionId': AUCTION_ID, 'bidderRequestId': '1be65d7958826a', - 'bids': [ { + 'bids': [{ 'bidder': 'adagio', 'params': { ...PARAMS_ADG @@ -514,7 +514,7 @@ const AUCTION_INIT_CACHE = { 'auctionId': AUCTION_ID_CACHE, 'timestamp': 1519767010567, 'auctionStatus': 'inProgress', - 'adUnits': [ { + 'adUnits': [{ 'code': '/19968336/header-bid-tag-1', 'mediaTypes': { 'banner': { @@ -531,7 +531,7 @@ const AUCTION_INIT_CACHE = { } }, 'sizes': [[640, 480]], - 'bids': [ { + 'bids': [{ 'bidder': 'another', 'params': { 'publisherId': '1001' @@ -541,7 +541,7 @@ const AUCTION_INIT_CACHE = { 'params': { ...PARAMS_ADG }, - }, ], + },], 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', 'ortb2Imp': { 'ext': { @@ -561,20 +561,20 @@ const AUCTION_INIT_CACHE = { } }, 'sizes': [[640, 480]], - 'bids': [ { + 'bids': [{ 'bidder': 'another', 'params': { 'publisherId': '1001' }, - } ], + }], 'transactionId': 'ca4af27a-6d02-4f90-949d-d5541fa12014', - } ], + }], 'adUnitCodes': ['/19968336/header-bid-tag-1', '/19968336/footer-bid-tag-1'], - 'bidderRequests': [ { + 'bidderRequests': [{ 'bidderCode': 'another', 'auctionId': AUCTION_ID_CACHE, 'bidderRequestId': '1be65d7958826a', - 'bids': [ { + 'bids': [{ 'bidder': 'another', 'params': { 'publisherId': '1001', @@ -638,7 +638,7 @@ const AUCTION_INIT_CACHE = { 'bidderCode': 'adagio', 'auctionId': AUCTION_ID_CACHE, 'bidderRequestId': '1be65d7958826a', - 'bids': [ { + 'bids': [{ 'bidder': 'adagio', 'params': { ...PARAMS_ADG diff --git a/test/spec/modules/adagioBidAdapter_spec.js b/test/spec/modules/adagioBidAdapter_spec.js index 45788fe14a6..e774b49da0d 100644 --- a/test/spec/modules/adagioBidAdapter_spec.js +++ b/test/spec/modules/adagioBidAdapter_spec.js @@ -12,7 +12,7 @@ import { config } from '../../../src/config.js'; import { executeRenderer } from '../../../src/Renderer.js'; import { expect } from 'chai'; import { userSync } from '../../../src/userSync.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const BidRequestBuilder = function BidRequestBuilder(options) { const defaults = { @@ -197,12 +197,14 @@ describe('Adagio bid adapter', () => { }); it('should use adUnit code for adUnitElementId and placement params', function() { - const bid01 = new BidRequestBuilder({ params: { - organizationId: '1000', - site: 'site-name', - useAdUnitCodeAsPlacement: true, - useAdUnitCodeAsAdUnitElementId: true - }}).build(); + const bid01 = new BidRequestBuilder({ + params: { + organizationId: '1000', + site: 'site-name', + useAdUnitCodeAsPlacement: true, + useAdUnitCodeAsAdUnitElementId: true + } + }).build(); expect(spec.isBidRequestValid(bid01)).to.equal(true); expect(bid01.params.adUnitElementId).to.equal('adunit-code'); @@ -210,20 +212,26 @@ describe('Adagio bid adapter', () => { }); it('should return false when a required param is missing', function() { - const bid01 = new BidRequestBuilder({ params: { - organizationId: '1000', - placement: 'PAVE_ATF' - }}).build(); + const bid01 = new BidRequestBuilder({ + params: { + organizationId: '1000', + placement: 'PAVE_ATF' + } + }).build(); - const bid02 = new BidRequestBuilder({ params: { - organizationId: '1000', - site: 'SITE-NAME' - }}).build(); + const bid02 = new BidRequestBuilder({ + params: { + organizationId: '1000', + site: 'SITE-NAME' + } + }).build(); - const bid03 = new BidRequestBuilder({ params: { - placement: 'PAVE_ATF', - site: 'SITE-NAME' - }}).build(); + const bid03 = new BidRequestBuilder({ + params: { + placement: 'PAVE_ATF', + site: 'SITE-NAME' + } + }).build(); sandbox.stub(config, 'getConfig').withArgs('adagio').returns({ siteId: '1000' @@ -423,7 +431,9 @@ describe('Adagio bid adapter', () => { dom_loading: '111111111', } } - }}} + } + } + } }, ortb2Imp: { ext: { @@ -896,8 +906,8 @@ describe('Adagio bid adapter', () => { const requests = spec.buildRequests([bid01], bidderRequest); expect(requests[0].data.adUnits[0].mediaTypes.banner.sizes.length).to.equal(2); - expect(requests[0].data.adUnits[0].mediaTypes.banner.bannerSizes[0]).to.deep.equal({size: [300, 250], floor: 1}); - expect(requests[0].data.adUnits[0].mediaTypes.banner.bannerSizes[1]).to.deep.equal({size: [300, 600], floor: 1}); + expect(requests[0].data.adUnits[0].mediaTypes.banner.bannerSizes[0]).to.deep.equal({ size: [300, 250], floor: 1 }); + expect(requests[0].data.adUnits[0].mediaTypes.banner.bannerSizes[1]).to.deep.equal({ size: [300, 600], floor: 1 }); expect(requests[0].data.adUnits[0].mediaTypes.video.floor).to.equal(1); }); @@ -1060,12 +1070,12 @@ describe('Adagio bid adapter', () => { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }, }; const bid01 = new BidRequestBuilder().withParams().build(); - const bidderRequest = new BidderRequestBuilder({ortb2}).build(); + const bidderRequest = new BidderRequestBuilder({ ortb2 }).build(); const requests = spec.buildRequests([bid01], bidderRequest); const expectedData = { @@ -1361,7 +1371,7 @@ describe('Adagio bid adapter', () => { }); it('should logError if correct renderer is not defined', function() { - window.bluebillywig = { renderers: [ { _id: 'adagio-another_renderer' } ] }; + window.bluebillywig = { renderers: [{ _id: 'adagio-another_renderer' }] }; utilsMock.expects('logError').withExactArgs('Adagio: couldn\'t find a renderer with ID adagio-renderer').once(); diff --git a/test/spec/modules/adagioRtdProvider_spec.js b/test/spec/modules/adagioRtdProvider_spec.js index 3ac2d1fa73f..800590e8826 100644 --- a/test/spec/modules/adagioRtdProvider_spec.js +++ b/test/spec/modules/adagioRtdProvider_spec.js @@ -127,7 +127,7 @@ describe('Adagio Rtd Provider', function () { }; it('store new session data for further usage', function () { - const storageValue = JSON.stringify({abTest: {}}); + const storageValue = JSON.stringify({ abTest: {} }); sandbox.stub(storage, 'getDataFromLocalStorage').callsArgWith(1, storageValue); sandbox.stub(Date, 'now').returns(1714116520710); sandbox.stub(Math, 'random').returns(0.8); @@ -155,7 +155,7 @@ describe('Adagio Rtd Provider', function () { }); it('store existing session data for further usage', function () { - const storageValue = JSON.stringify({session: session, abTest: {}}); + const storageValue = JSON.stringify({ session: session, abTest: {} }); sandbox.stub(storage, 'getDataFromLocalStorage').callsArgWith(1, storageValue); sandbox.stub(Date, 'now').returns(1714116520710); sandbox.stub(Math, 'random').returns(0.8); @@ -179,7 +179,7 @@ describe('Adagio Rtd Provider', function () { }); it('store new session if old session has expired data for further usage', function () { - const storageValue = JSON.stringify({session: session, abTest: {}}); + const storageValue = JSON.stringify({ session: session, abTest: {} }); sandbox.stub(Date, 'now').returns(1715679344351); sandbox.stub(storage, 'getDataFromLocalStorage').callsArgWith(1, storageValue); sandbox.stub(Math, 'random').returns(0.8); @@ -422,8 +422,8 @@ describe('Adagio Rtd Provider', function () { ext: { geom() { return { - win: {t: 23, r: 1920, b: 1200, l: 0, w: 1920, h: 1177}, - self: {t: 210, r: 1159, b: 460, l: 859, w: 300, h: 250}, + win: { t: 23, r: 1920, b: 1200, l: 0, w: 1920, h: 1177 }, + self: { t: 210, r: 1159, b: 460, l: 859, w: 300, h: 250 }, } } } @@ -705,7 +705,8 @@ describe('Adagio Rtd Provider', function () { mediaTypes, params, auctionId, - bidderRequestsCount } = bidderRequestCopy.bids[0]; + bidderRequestsCount + } = bidderRequestCopy.bids[0]; const expected = { bidder, diff --git a/test/spec/modules/adbroBidAdapter_spec.js b/test/spec/modules/adbroBidAdapter_spec.js index 56fca4dbec1..f22b161e8c0 100644 --- a/test/spec/modules/adbroBidAdapter_spec.js +++ b/test/spec/modules/adbroBidAdapter_spec.js @@ -20,7 +20,7 @@ describe('adbroBidAdapter', function () { } }; - const validBid = makeBid({placementId: '1234'}, [[300, 250]]); + const validBid = makeBid({ placementId: '1234' }, [[300, 250]]); const invalidBid = makeBid({}, [[300, 250]]); const bidderRequest = { @@ -47,13 +47,13 @@ describe('adbroBidAdapter', function () { expect(spec.isBidRequestValid(makeBid({}, [[300, 250]]))).to.be.false; }); it('Should return false if banner sizes are not presented', function () { - expect(spec.isBidRequestValid(makeBid({placementId: '1234'}))).to.be.false; - expect(spec.isBidRequestValid(makeBid({placementId: '1234'}, []))).to.be.false; + expect(spec.isBidRequestValid(makeBid({ placementId: '1234' }))).to.be.false; + expect(spec.isBidRequestValid(makeBid({ placementId: '1234' }, []))).to.be.false; }); it('Should return true if placementId is an integer', function () { - expect(spec.isBidRequestValid(makeBid({placementId: '1234'}, [[300, 250]]))).to.be.true; - expect(spec.isBidRequestValid(makeBid({placementId: '1234'}, [[300, 250]]))).to.be.true; - expect(spec.isBidRequestValid(makeBid({placementId: 'abc'}, [[300, 250]]))).to.be.false; + expect(spec.isBidRequestValid(makeBid({ placementId: '1234' }, [[300, 250]]))).to.be.true; + expect(spec.isBidRequestValid(makeBid({ placementId: '1234' }, [[300, 250]]))).to.be.true; + expect(spec.isBidRequestValid(makeBid({ placementId: 'abc' }, [[300, 250]]))).to.be.false; }); }); @@ -121,11 +121,13 @@ describe('adbroBidAdapter', function () { h: 250, }; const bidRequest = spec.buildRequests([validBid], bidderRequest)[0]; - const bidResponse = {body: { - id: bidRequest.data.id, - bidid: utils.getUniqueIdentifierStr(), - seatbid: [{bid: [responseBid]}], - }}; + const bidResponse = { + body: { + id: bidRequest.data.id, + bidid: utils.getUniqueIdentifierStr(), + seatbid: [{ bid: [responseBid] }], + } + }; const responses = spec.interpretResponse(bidResponse, bidRequest); expect(responses).to.be.an('array').that.is.not.empty; const response = responses[0]; @@ -147,29 +149,33 @@ describe('adbroBidAdapter', function () { it('Should return an empty array if invalid banner response is passed', function () { const bidRequest = spec.buildRequests([validBid], bidderRequest)[0]; - const bidResponse = {body: { - id: bidRequest.data.id, - bidid: utils.getUniqueIdentifierStr(), - seatbid: [{ - bid: [{ - id: utils.getUniqueIdentifierStr(), - impid: invalidBid.bidId, - price: 0.4, - w: 300, - h: 250, + const bidResponse = { + body: { + id: bidRequest.data.id, + bidid: utils.getUniqueIdentifierStr(), + seatbid: [{ + bid: [{ + id: utils.getUniqueIdentifierStr(), + impid: invalidBid.bidId, + price: 0.4, + w: 300, + h: 250, + }], }], - }], - }}; + } + }; const responses = spec.interpretResponse(bidResponse, bidRequest); expect(responses).to.be.an('array').that.is.empty; }); it('Should return an empty array if no seat bids are passed', function () { const bidRequest = spec.buildRequests([validBid], bidderRequest)[0]; - const bidResponse = {body: { - id: bidRequest.data.id, - bidid: utils.getUniqueIdentifierStr(), - }}; + const bidResponse = { + body: { + id: bidRequest.data.id, + bidid: utils.getUniqueIdentifierStr(), + } + }; const responses = spec.interpretResponse(bidResponse, bidRequest); expect(responses).to.be.an('array').that.is.empty; }); @@ -190,7 +196,7 @@ describe('adbroBidAdapter', function () { }); it('Should trigger billing URL pixel', function () { - spec.onBidBillable({burl: pixel}); + spec.onBidBillable({ burl: pixel }); sinon.assert.calledOnce(triggerPixelStub); sinon.assert.calledWith(triggerPixelStub, pixel); }); diff --git a/test/spec/modules/adclusterBidAdapter_spec.js b/test/spec/modules/adclusterBidAdapter_spec.js new file mode 100644 index 00000000000..d068a0b5944 --- /dev/null +++ b/test/spec/modules/adclusterBidAdapter_spec.js @@ -0,0 +1,415 @@ +// test/spec/modules/adclusterBidAdapter_spec.js + +import { expect } from "chai"; +import { spec } from "modules/adclusterBidAdapter.js"; // adjust path if needed +import { BANNER, VIDEO } from "src/mediaTypes.js"; + +const BIDDER_CODE = "adcluster"; +const ENDPOINT = "https://core.adcluster.com.tr/bid"; + +describe("adclusterBidAdapter", function () { + // ---------- Test Fixtures (immutable) ---------- + const baseBid = Object.freeze({ + bidder: BIDDER_CODE, + bidId: "2f5d", + bidderRequestId: "breq-1", + auctionId: "auc-1", + transactionId: "txn-1", + adUnitCode: "div-1", + adUnitId: "adunit-1", + params: { unitId: "61884b5c-9420-4f15-871f-2dcc2fa1cff5" }, + }); + + const gdprConsent = Object.freeze({ + gdprApplies: true, + consentString: "BOJ/P2HOJ/P2HABABMAAAAAZ+A==", + }); + + const uspConsent = "1---"; + const gpp = "DBABLA.."; + const gppSid = [7, 8]; + + const bidderRequestBase = Object.freeze({ + auctionId: "auc-1", + bidderCode: BIDDER_CODE, + bidderRequestId: "breq-1", + auctionStart: 1111111111111, + timeout: 2000, + start: 1111111111112, + ortb2: { regs: { gpp, gpp_sid: gppSid } }, + gdprConsent, + uspConsent, + }); + + // helpers return fresh objects to avoid cross-test mutation + function mkBidBanner(extra = {}) { + return { + ...baseBid, + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 600], + ], + }, + }, + getFloor: ({ mediaType }) => { + if (mediaType === "banner") return { currency: "USD", floor: 0.5 }; + return { currency: "USD", floor: 0.0 }; + }, + userIdAsEids: [ + { source: "example.com", uids: [{ id: "abc", atype: 1 }] }, + ], + ortb2: { + source: { ext: { schain: { ver: "1.0", complete: 1, nodes: [] } } }, + }, + ...extra, + }; + } + + function mkBidVideo(extra = {}) { + return { + ...baseBid, + mediaTypes: { + video: { + context: "instream", + playerSize: [640, 360], + minduration: 5, + maxduration: 30, + }, + }, + getFloor: ({ mediaType, size }) => { + if (mediaType === "video" && Array.isArray(size)) { + return { currency: "USD", floor: 1.2 }; + } + return { currency: "USD", floor: 0.0 }; + }, + userIdAsEids: [ + { source: "example.com", uids: [{ id: "xyz", atype: 1 }] }, + ], + ortb2: { + source: { ext: { schain: { ver: "1.0", complete: 1, nodes: [] } } }, + }, + ...extra, + }; + } + + describe("isBidRequestValid", function () { + it("returns true when params.unitId is present", function () { + // Arrange + const bid = { ...baseBid }; + + // Act + const valid = spec.isBidRequestValid(bid); + + // Assert + expect(valid).to.equal(true); + }); + + it("returns false when params.unitId is missing", function () { + // Arrange + const bid = { ...baseBid, params: {} }; + + // Act + const valid = spec.isBidRequestValid(bid); + + // Assert + expect(valid).to.equal(false); + }); + + it("returns false when params is undefined", function () { + // Arrange + const bid = { ...baseBid, params: undefined }; + + // Act + const valid = spec.isBidRequestValid(bid); + + // Assert + expect(valid).to.equal(false); + }); + }); + + describe("buildRequests", function () { + it("builds a POST request with JSON body to the right endpoint", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidBanner(), mkBidVideo()]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + expect(req.method).to.equal("POST"); + expect(req.url).to.equal(ENDPOINT); + expect(req.options).to.deep.equal({ contentType: "text/plain" }); + expect(req.data).to.be.an("object"); + expect(req.data.bidderCode).to.equal(BIDDER_CODE); + expect(req.data.auctionId).to.equal(br.auctionId); + expect(req.data.bids).to.be.an("array").with.length(2); + }); + + it("includes privacy signals (GDPR, USP, GPP) when present", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidBanner()]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + const { regs, user } = req.data; + expect(regs).to.be.an("object"); + expect(regs.ext.gdpr).to.equal(1); + expect(user.ext.consent).to.equal(gdprConsent.consentString); + expect(regs.ext.us_privacy).to.equal(uspConsent); + expect(regs.ext.gpp).to.equal(gpp); + expect(regs.ext.gppSid).to.deep.equal(gppSid); + }); + + it("omits privacy fields when not provided", function () { + // Arrange + const minimalBR = { + auctionId: "auc-2", + bidderCode: BIDDER_CODE, + bidderRequestId: "breq-2", + auctionStart: 1, + timeout: 1000, + start: 2, + }; + const bids = [mkBidBanner()]; + + // Act + const req = spec.buildRequests(bids, minimalBR); + + // Assert + // regs.ext should exist but contain no privacy flags + expect(req.data.regs).to.be.an("object"); + expect(req.data.regs.ext).to.deep.equal({}); + // user.ext.consent must be undefined when no GDPR + expect(req.data.user).to.be.an("object"); + expect(req.data.user.ext).to.be.an("object"); + expect(req.data.user.ext.consent).to.be.undefined; + // allow eids to be present (they come from bids) + // don't assert deep-equality on user.ext, just ensure no privacy fields + expect(req.data.user.ext.gdpr).to.be.undefined; + }); + + it("passes userIdAsEids and schain when provided", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidBanner()]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + expect(req.data.user.ext.eids).to.be.an("array").with.length(1); + expect(req.data.source.ext.schain).to.be.an("object"); + }); + + it("sets banner dimensions from first size and includes floors ext", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidBanner()]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + const imp = req.data.bids[0]; + expect(imp.width).to.equal(300); + expect(imp.height).to.equal(250); + expect(imp.ext).to.have.property("floors"); + expect(imp.ext.floors.banner).to.equal(0.5); + }); + + it("sets video sizes from playerSize and includes video floors", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidVideo()]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + const imp = req.data.bids[0]; + expect(imp.width).to.equal(640); + expect(imp.height).to.equal(360); + expect(imp.video).to.be.an("object"); + expect(imp.video.minduration).to.equal(5); + expect(imp.video.maxduration).to.equal(30); + expect(imp.video.ext.context).to.equal("instream"); + expect(imp.video.ext.floor).to.equal(1.2); + expect(imp.ext.floors.video).to.equal(1.2); + }); + + it("gracefully handles missing getFloor", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [mkBidBanner({ getFloor: undefined })]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + expect(req.data.bids[0].ext.floors.banner).to.equal(null); + }); + + it("passes previewMediaId when provided", function () { + // Arrange + const br = { ...bidderRequestBase }; + const bids = [ + mkBidVideo({ params: { unitId: "x", previewMediaId: "media-123" } }), + ]; + + // Act + const req = spec.buildRequests(bids, br); + + // Assert + expect(req.data.bids[0].params.previewMediaId).to.equal("media-123"); + }); + }); + + describe("interpretResponse", function () { + it("returns empty array when body is missing or not an array", function () { + // Arrange + const missing = { body: null }; + const notArray = { body: {} }; + + // Act + const out1 = spec.interpretResponse(missing); + const out2 = spec.interpretResponse(notArray); + + // Assert + expect(out1).to.deep.equal([]); + expect(out2).to.deep.equal([]); + }); + + it("maps banner responses to Prebid bids", function () { + // Arrange + const serverBody = [ + { + requestId: "2f5d", + cpm: 1.23, + currency: "USD", + width: 300, + height: 250, + creativeId: "cr-1", + ttl: 300, + netRevenue: true, + mediaType: "banner", + ad: "
creative
", + meta: { advertiserDomains: ["advertiser.com"] }, + }, + ]; + + // Act + const out = spec.interpretResponse({ body: serverBody }); + + // Assert + expect(out).to.have.length(1); + const b = out[0]; + expect(b.requestId).to.equal("2f5d"); + expect(b.cpm).to.equal(1.23); + expect(b.mediaType).to.equal(BANNER); + expect(b.ad).to.be.a("string"); + expect(b.meta.advertiserDomains).to.deep.equal(["advertiser.com"]); + }); + + it("maps video responses to Prebid bids (vastUrl)", function () { + // Arrange + const serverBody = [ + { + requestId: "vid-1", + cpm: 2.5, + currency: "USD", + width: 640, + height: 360, + creativeId: "cr-v", + ttl: 300, + netRevenue: true, + mediaType: "video", + ad: "https://vast.tag/url.xml", + meta: { advertiserDomains: ["brand.com"] }, // mediaType hint optional + }, + ]; + + // Act + const out = spec.interpretResponse({ body: serverBody }); + + // Assert + expect(out).to.have.length(1); + const b = out[0]; + expect(b.requestId).to.equal("vid-1"); + expect(b.mediaType).to.equal(VIDEO); + expect(b.vastUrl).to.equal("https://vast.tag/url.xml"); + expect(b.ad).to.be.undefined; + }); + + it("handles missing meta.advertiserDomains safely", function () { + // Arrange + const serverBody = [ + { + requestId: "2f5d", + cpm: 0.2, + currency: "USD", + width: 300, + height: 250, + creativeId: "cr-2", + ttl: 120, + netRevenue: true, + ad: "
", + meta: {}, + }, + ]; + + // Act + const out = spec.interpretResponse({ body: serverBody }); + + // Assert + expect(out[0].meta.advertiserDomains).to.deep.equal([]); + }); + + it("supports multiple mixed responses", function () { + // Arrange + const serverBody = [ + { + requestId: "b-1", + cpm: 0.8, + currency: "USD", + width: 300, + height: 250, + creativeId: "cr-b", + ttl: 300, + netRevenue: true, + ad: "
banner
", + mediaType: "banner", + meta: { advertiserDomains: [] }, + }, + { + requestId: "v-1", + cpm: 3.1, + currency: "USD", + width: 640, + height: 360, + creativeId: "cr-v", + ttl: 300, + netRevenue: true, + mediaType: "video", + ad: "https://vast.example/vast.xml", + meta: { advertiserDomains: ["x.com"] }, + }, + ]; + + // Act + const out = spec.interpretResponse({ body: serverBody }); + + // Assert + expect(out).to.have.length(2); + const [b, v] = out; + expect(b.mediaType).to.equal(BANNER); + expect(v.mediaType).to.equal(VIDEO); + expect(v.vastUrl).to.match(/^https:\/\/vast\.example/); + }); + }); +}); diff --git a/test/spec/modules/addefendBidAdapter_spec.js b/test/spec/modules/addefendBidAdapter_spec.js index 7faa30c69be..f4449b4a9cf 100644 --- a/test/spec/modules/addefendBidAdapter_spec.js +++ b/test/spec/modules/addefendBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/addefendBidAdapter.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { expect } from 'chai'; +import { spec } from 'modules/addefendBidAdapter.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('addefendBidAdapter', () => { const defaultBidRequest = { @@ -84,12 +84,12 @@ describe('addefendBidAdapter', () => { it('sends correct bid parameters', () => { const bidRequest = deepClone(defaultBidRequest); - expect(request.data.bids).to.deep.equal([ { + expect(request.data.bids).to.deep.equal([{ bidId: bidRequest.bidId, placementId: bidRequest.params.placementId, - sizes: [ '300x250', '300x600' ], + sizes: ['300x250', '300x600'], transactionId: 'd58851660c0c4461e4aa06344fc9c0c6' - } ]); + }]); }); it('handles empty gdpr object', () => { @@ -154,7 +154,7 @@ describe('addefendBidAdapter', () => { } ]; - const result = spec.interpretResponse({body: serverResponse}); + const result = spec.interpretResponse({ body: serverResponse }); expect(result.length).to.equal(expectedResponse.length); Object.keys(expectedResponse[0]).forEach((key) => { expect(result[0][key]).to.deep.equal(expectedResponse[0][key]); @@ -170,14 +170,14 @@ describe('addefendBidAdapter', () => { 'ttl': 60 } ]; - const result = spec.interpretResponse({body: serverResponse}); + const result = spec.interpretResponse({ body: serverResponse }); expect(result.length).to.equal(0); }); it('handles nobid responses', () => { const serverResponse = []; - const result = spec.interpretResponse({body: serverResponse}); + const result = spec.interpretResponse({ body: serverResponse }); expect(result.length).to.equal(0); }); diff --git a/test/spec/modules/adfBidAdapter_spec.js b/test/spec/modules/adfBidAdapter_spec.js index bc15ab40c7d..2743c2fb3cc 100644 --- a/test/spec/modules/adfBidAdapter_spec.js +++ b/test/spec/modules/adfBidAdapter_spec.js @@ -129,7 +129,7 @@ describe('Adf adapter', function () { }); it('should transfer DSA info', function () { - const validBidRequests = [ { bidId: 'bidId', params: { siteId: 'siteId' } } ]; + const validBidRequests = [{ bidId: 'bidId', params: { siteId: 'siteId' } }]; const request = JSON.parse( spec.buildRequests(validBidRequests, { @@ -201,8 +201,8 @@ describe('Adf adapter', function () { params: { siteId: 'siteId' }, }]; const request = JSON.parse(spec.buildRequests(validBidRequests, { - refererInfo: {page: 'page'}, - ortb2: {source: {tid: 'tid'}} + refererInfo: { page: 'page' }, + ortb2: { source: { tid: 'tid' } } }).data); assert.equal(request.source.tid, 'tid'); @@ -278,8 +278,8 @@ describe('Adf adapter', function () { bidId: 'bidId', params: {}, userIdAsEids: [ - { source: 'adserver.org', uids: [ { id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } } ] }, - { source: 'pubcid.org', uids: [ { id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 } ] } + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ] }]; @@ -294,7 +294,7 @@ describe('Adf adapter', function () { setCurrencyConfig({ adServerCurrency: 'EUR' }) return addFPDToBidderRequest(bidderRequest).then(res => { const request = JSON.parse(spec.buildRequests(validBidRequests, res).data); - assert.deepEqual(request.cur, [ 'EUR' ]); + assert.deepEqual(request.cur, ['EUR']); setCurrencyConfig({}); }); }); @@ -364,15 +364,15 @@ describe('Adf adapter', function () { const validBidRequests = [{ bidId: 'bidId', params: { mid: '1000' }, - mediaTypes: {video: {}} + mediaTypes: { video: {} } }, { bidId: 'bidId2', params: { mid: '1000' }, - mediaTypes: {video: {}} + mediaTypes: { video: {} } }, { bidId: 'bidId3', params: { mid: '1000' }, - mediaTypes: {video: {}} + mediaTypes: { video: {} } }]; const imps = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }).data).imp; @@ -382,9 +382,9 @@ describe('Adf adapter', function () { }); it('should add mid', function () { - const validBidRequests = [{ bidId: 'bidId', params: {mid: 1000}, mediaTypes: {video: {}} }, - { bidId: 'bidId2', params: {mid: 1001}, mediaTypes: {video: {}} }, - { bidId: 'bidId3', params: {mid: 1002}, mediaTypes: {video: {}} }]; + const validBidRequests = [{ bidId: 'bidId', params: { mid: 1000 }, mediaTypes: { video: {} } }, + { bidId: 'bidId2', params: { mid: 1001 }, mediaTypes: { video: {} } }, + { bidId: 'bidId3', params: { mid: 1002 }, mediaTypes: { video: {} } }]; const imps = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }).data).imp; for (let i = 0; i < 3; i++) { assert.equal(imps[i].tagid, validBidRequests[i].params.mid); @@ -411,11 +411,11 @@ describe('Adf adapter', function () { describe('dynamic placement tag', function () { it('should add imp parameters correctly', function () { const validBidRequests = [ - { bidId: 'bidId', params: { inv: 1000, mname: 'placement' }, mediaTypes: {video: {}} }, - { bidId: 'bidId', params: { mid: 1234, inv: 1002, mname: 'placement2' }, mediaTypes: {video: {}} }, - { bidId: 'bidId', params: { mid: 1234 }, mediaTypes: {video: {}} } + { bidId: 'bidId', params: { inv: 1000, mname: 'placement' }, mediaTypes: { video: {} } }, + { bidId: 'bidId', params: { mid: 1234, inv: 1002, mname: 'placement2' }, mediaTypes: { video: {} } }, + { bidId: 'bidId', params: { mid: 1234 }, mediaTypes: { video: {} } } ]; - const [ imp1, imp2, imp3 ] = getRequestImps(validBidRequests); + const [imp1, imp2, imp3] = getRequestImps(validBidRequests); assert.equal(imp1.ext.bidder.inv, 1000); assert.equal(imp1.ext.bidder.mname, 'placement'); @@ -434,7 +434,7 @@ describe('Adf adapter', function () { describe('price floors', function () { it('should not add if floors module not configured', function () { - const validBidRequests = [{ bidId: 'bidId', params: {mid: 1000}, mediaTypes: {video: {}} }]; + const validBidRequests = [{ bidId: 'bidId', params: { mid: 1000 }, mediaTypes: { video: {} } }]; const imp = getRequestImps(validBidRequests)[0]; assert.equal(imp.bidfloor, undefined); @@ -442,7 +442,7 @@ describe('Adf adapter', function () { }); it('should not add if floor price not defined', function () { - const validBidRequests = [ getBidWithFloor() ]; + const validBidRequests = [getBidWithFloor()]; const imp = getRequestImps(validBidRequests)[0]; assert.equal(imp.bidfloor, undefined); @@ -451,7 +451,7 @@ describe('Adf adapter', function () { it('should request floor price in adserver currency', function () { setCurrencyConfig({ adServerCurrency: 'DKK' }) - const validBidRequests = [ getBidWithFloor() ]; + const validBidRequests = [getBidWithFloor()]; return addFPDToBidderRequest(validBidRequests[0]).then(res => { const imp = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' }, ...res }).data).imp[0]; assert.equal(imp.bidfloor, undefined); @@ -461,7 +461,7 @@ describe('Adf adapter', function () { }); it('should add correct floor values', function () { - const expectedFloors = [ 1, 1.3, 0.5 ]; + const expectedFloors = [1, 1.3, 0.5]; const validBidRequests = expectedFloors.map(getBidWithFloor); const imps = getRequestImps(validBidRequests); @@ -473,18 +473,22 @@ describe('Adf adapter', function () { it('should add correct params to getFloor', function () { let result; - let mediaTypes = { video: { - playerSize: [ 100, 200 ] - } }; - const expectedFloors = [ 1, 1.3, 0.5 ]; + let mediaTypes = { + video: { + playerSize: [100, 200] + } + }; + const expectedFloors = [1, 1.3, 0.5]; setCurrencyConfig({ adServerCurrency: 'DKK' }); const validBidRequests = expectedFloors.map(getBidWithFloorTest); return addFPDToBidderRequest(validBidRequests[0]).then(res => { getRequestImps(validBidRequests, res); assert.deepEqual(result, { currency: 'DKK', size: '*', mediaType: '*' }) - mediaTypes = { banner: { - sizes: [ [100, 200], [300, 400] ] - }}; + mediaTypes = { + banner: { + sizes: [[100, 200], [300, 400]] + } + }; getRequestImps(validBidRequests, res); assert.deepEqual(result, { currency: 'DKK', size: '*', mediaType: '*' }); @@ -573,7 +577,7 @@ describe('Adf adapter', function () { video: {} } }]; - const [ first, second, third ] = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }).data).imp; + const [first, second, third] = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }).data).imp; assert.ok(first.banner); assert.ok(first.video); @@ -602,7 +606,7 @@ describe('Adf adapter', function () { }]; const { banner } = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }).data).imp[0]; assert.deepEqual(banner, { - format: [ { w: 100, h: 100 }, { w: 200, h: 300 } ] + format: [{ w: 100, h: 100 }, { w: 200, h: 300 }] }); }); }); @@ -709,7 +713,7 @@ describe('Adf adapter', function () { hmin: 627, w: 325, h: 300, - mimes: [ 'image/jpg', 'image/gif' ] + mimes: ['image/jpg', 'image/gif'] } }, { @@ -900,9 +904,9 @@ describe('Adf adapter', function () { const serverResponse = { body: { seatbid: [{ - bid: [{impid: '1', native: {ver: '1.1', link: { url: 'link' }, assets: [{id: 0, title: {text: 'Asset title text'}}]}}] + bid: [{ impid: '1', native: { ver: '1.1', link: { url: 'link' }, assets: [{ id: 0, title: { text: 'Asset title text' } }] } }] }, { - bid: [{impid: '2', native: {ver: '1.1', link: { url: 'link' }, assets: [{id: 1, data: {value: 'Asset title text'}}]}}] + bid: [{ impid: '2', native: { ver: '1.1', link: { url: 'link' }, assets: [{ id: 1, data: { value: 'Asset title text' } }] } }] }] } }; @@ -943,11 +947,11 @@ describe('Adf adapter', function () { body: { seatbid: [{ bid: [ - {impid: '1', native: {ver: '1.1', link: { url: 'link1' }, assets: [{id: 0, title: {text: 'Asset title text'}}]}}, - {impid: '4', native: {ver: '1.1', link: { url: 'link4' }, assets: [{id: 1, title: {text: 'Asset title text'}}]}} + { impid: '1', native: { ver: '1.1', link: { url: 'link1' }, assets: [{ id: 0, title: { text: 'Asset title text' } }] } }, + { impid: '4', native: { ver: '1.1', link: { url: 'link4' }, assets: [{ id: 1, title: { text: 'Asset title text' } }] } } ] }, { - bid: [{impid: '2', native: {ver: '1.1', link: { url: 'link2' }, assets: [{id: 0, data: {value: 'Asset title text'}}]}}] + bid: [{ impid: '2', native: { ver: '1.1', link: { url: 'link2' }, assets: [{ id: 0, data: { value: 'Asset title text' } }] } }] }] } }; @@ -1003,11 +1007,11 @@ describe('Adf adapter', function () { bids = spec.interpretResponse(serverResponse, bidRequest).map(bid => { const { requestId, native: { ortb: { link: { url } } } } = bid; - return [ requestId, url ]; + return [requestId, url]; }); assert.equal(bids.length, 3); - assert.deepEqual(bids, [[ 'bidId1', 'link1' ], [ 'bidId2', 'link2' ], [ 'bidId4', 'link4' ]]); + assert.deepEqual(bids, [['bidId1', 'link1'], ['bidId2', 'link2'], ['bidId4', 'link4']]); }); it('should set correct values to bid', function () { @@ -1027,7 +1031,7 @@ describe('Adf adapter', function () { imptrackers: ['imptrackers url1', 'imptrackers url2'] }, dealid: 'deal-id', - adomain: [ 'demo.com' ], + adomain: ['demo.com'], ext: { prebid: { type: 'native', @@ -1042,7 +1046,7 @@ describe('Adf adapter', function () { adrender: 1 } }, - cat: [ 'IAB1', 'IAB2' ] + cat: ['IAB1', 'IAB2'] } ] }], @@ -1103,8 +1107,8 @@ describe('Adf adapter', function () { assert.deepEqual(bids[0].mediaType, 'native'); assert.deepEqual(bids[0].meta.mediaType, 'native'); assert.deepEqual(bids[0].meta.primaryCatId, 'IAB1'); - assert.deepEqual(bids[0].meta.secondaryCatIds, [ 'IAB2' ]); - assert.deepEqual(bids[0].meta.advertiserDomains, [ 'demo.com' ]); + assert.deepEqual(bids[0].meta.secondaryCatIds, ['IAB2']); + assert.deepEqual(bids[0].meta.advertiserDomains, ['demo.com']); assert.deepEqual(bids[0].meta.dsa, { behalf: 'some-behalf', paid: 'some-paid', @@ -1156,7 +1160,7 @@ describe('Adf adapter', function () { img: { url: 'test.url.com/Files/58345/308200.jpg?bv=1', w: 300, h: 300 } }], link: { - url: 'clickUrl', clicktrackers: [ 'clickTracker1', 'clickTracker2' ] + url: 'clickUrl', clicktrackers: ['clickTracker1', 'clickTracker2'] }, imptrackers: ['imptracker url1', 'imptracker url2'], jstracker: 'jstracker' @@ -1232,7 +1236,7 @@ describe('Adf adapter', function () { const native = bid[0].native; const assets = native.assets; - assert.deepEqual(result, {ortb: native}); + assert.deepEqual(result, { ortb: native }); }); it('should return empty when there is no bids in response', function () { const serverResponse = { diff --git a/test/spec/modules/adgenerationBidAdapter_spec.js b/test/spec/modules/adgenerationBidAdapter_spec.js index 8a542ba2966..73e872e9996 100644 --- a/test/spec/modules/adgenerationBidAdapter_spec.js +++ b/test/spec/modules/adgenerationBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adgenerationBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {NATIVE} from 'src/mediaTypes.js'; +import { expect } from 'chai'; +import { spec } from 'modules/adgenerationBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { NATIVE } from 'src/mediaTypes.js'; import prebid from 'package.json'; import { setConfig as setCurrencyConfig } from '../../../modules/currency.js'; import { addFPDToBidderRequest } from '../../helpers/fpd.js'; @@ -59,7 +59,7 @@ describe('AdgenerationAdapter', function () { ], mobile: 0 }; - const schainSmaple = {ver: '1.0', complete: 1, nodes: [{asi: 'indirectseller.com', sid: '00001', hp: 1}]}; + const schainSmaple = { ver: '1.0', complete: 1, nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1 }] }; const bidRequests = [ { // banner bidder: 'adg', @@ -151,13 +151,13 @@ describe('AdgenerationAdapter', function () { uid: 'id5-id-test-1234567890' }, imuid: 'i.KrAH6ZAZTJOnH5S4N2sogA', - uid2: {id: 'AgAAAAVacu1uAxgAxH+HJ8+nWlS2H4uVqr6i+HBDCNREHD8WKsio/x7D8xXFuq1cJycUU86yXfTH9Xe/4C8KkH+7UCiU7uQxhyD7Qxnv251pEs6K8oK+BPLYR+8BLY/sJKesa/koKwx1FHgUzIBum582tSy2Oo+7C6wYUaaV4QcLr/4LPA='}, + uid2: { id: 'AgAAAAVacu1uAxgAxH+HJ8+nWlS2H4uVqr6i+HBDCNREHD8WKsio/x7D8xXFuq1cJycUU86yXfTH9Xe/4C8KkH+7UCiU7uQxhyD7Qxnv251pEs6K8oK+BPLYR+8BLY/sJKesa/koKwx1FHgUzIBum582tSy2Oo+7C6wYUaaV4QcLr/4LPA=' }, }, - ortb2Imp: {ext: {gpid: '/1111/homepage#300x250'}}, + ortb2Imp: { ext: { gpid: '/1111/homepage#300x250' } }, ortb2: { site: { domain: 'localhost:9999', - publisher: {'domain': 'localhost:9999'}, + publisher: { 'domain': 'localhost:9999' }, page: 'http://localhost:9999/integrationExamples/gpt/hello_world.html', ref: 'http://localhost:9999/integrationExamples/gpt/hello_world.html' }, @@ -301,7 +301,7 @@ describe('AdgenerationAdapter', function () { } } } - const request = spec.buildRequests(bidRequests, {...bidderRequest, ortb2: criteoParams})[0]; + const request = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2: criteoParams })[0]; expect(request.data.ortb.user).to.deep.equal(criteoParams.user); }); @@ -354,7 +354,7 @@ describe('AdgenerationAdapter', function () { } }, } - const request = spec.buildRequests(bidRequests, {...bidderRequest, ortb2: idparams})[3]; + const request = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2: idparams })[3]; expect(request.data.ortb.user).to.deep.equal(idparams.user); // gpid @@ -388,7 +388,7 @@ describe('AdgenerationAdapter', function () { const bidRequests = { banner: { bidderRequest: { - ortb2: {ext: {prebid: {adServerCurrency: 'JPY'}}} + ortb2: { ext: { prebid: { adServerCurrency: 'JPY' } } } }, method: 'POST', url: 'https://api-test.scaleout.jp/adgen/prebid?id=15415&posall=SSPLOC&sdktype=0', @@ -1004,7 +1004,7 @@ describe('AdgenerationAdapter', function () { { id: 1, required: 1, - title: {text: 'Title'} + title: { text: 'Title' } }, { id: 2, @@ -1025,17 +1025,17 @@ describe('AdgenerationAdapter', function () { required: 1 }, { - data: {value: 'Description'}, + data: { value: 'Description' }, id: 5, required: 0 }, { - data: {value: 'CTA'}, + data: { value: 'CTA' }, id: 6, required: 0 }, { - data: {value: 'Sponsored'}, + data: { value: 'Sponsored' }, id: 4, required: 0 } @@ -1180,7 +1180,7 @@ describe('AdgenerationAdapter', function () { }; it('no bid responses', function () { - const result = spec.interpretResponse({body: serverResponse.noAd}, bidRequests.banner); + const result = spec.interpretResponse({ body: serverResponse.noAd }, bidRequests.banner); expect(result.length).to.equal(0); }); @@ -1192,7 +1192,7 @@ describe('AdgenerationAdapter', function () { } }; return addFPDToBidderRequest(bidderRequest).then(res => { - const sr = {body: serverResponse.normal.upperBillboard}; + const sr = { body: serverResponse.normal.upperBillboard }; const br = { bidderRequest: res, ...bidRequests.upperBillboard }; const result = spec.interpretResponse(sr, br)[0]; @@ -1210,7 +1210,7 @@ describe('AdgenerationAdapter', function () { }); it('handles banner responses for empty adomain', function () { - const result = spec.interpretResponse({body: serverResponse.emptyAdomain.banner}, bidRequests.banner)[0]; + const result = spec.interpretResponse({ body: serverResponse.emptyAdomain.banner }, bidRequests.banner)[0]; expect(result.requestId).to.equal(bidResponses.normal.banner.requestId); expect(result.width).to.equal(bidResponses.normal.banner.width); expect(result.height).to.equal(bidResponses.normal.banner.height); @@ -1226,7 +1226,7 @@ describe('AdgenerationAdapter', function () { }); it('handles native responses for empty adomain', function () { - const result = spec.interpretResponse({body: serverResponse.emptyAdomain.native}, bidRequests.native)[0]; + const result = spec.interpretResponse({ body: serverResponse.emptyAdomain.native }, bidRequests.native)[0]; expect(result.requestId).to.equal(bidResponses.normal.native.requestId); expect(result.width).to.equal(bidResponses.normal.native.width); expect(result.height).to.equal(bidResponses.normal.native.height); @@ -1256,7 +1256,7 @@ describe('AdgenerationAdapter', function () { }); it('handles banner responses for no adomain', function () { - const result = spec.interpretResponse({body: serverResponse.noAdomain.banner}, bidRequests.banner)[0]; + const result = spec.interpretResponse({ body: serverResponse.noAdomain.banner }, bidRequests.banner)[0]; expect(result.requestId).to.equal(bidResponses.normal.banner.requestId); expect(result.width).to.equal(bidResponses.normal.banner.width); expect(result.height).to.equal(bidResponses.normal.banner.height); @@ -1272,7 +1272,7 @@ describe('AdgenerationAdapter', function () { }); it('handles native responses for no adomain', function () { - const result = spec.interpretResponse({body: serverResponse.noAdomain.native}, bidRequests.native)[0]; + const result = spec.interpretResponse({ body: serverResponse.noAdomain.native }, bidRequests.native)[0]; expect(result.requestId).to.equal(bidResponses.normal.native.requestId); expect(result.width).to.equal(bidResponses.normal.native.width); expect(result.height).to.equal(bidResponses.normal.native.height); diff --git a/test/spec/modules/adhashBidAdapter_spec.js b/test/spec/modules/adhashBidAdapter_spec.js index 75ff8b851f0..be48a3cace1 100644 --- a/test/spec/modules/adhashBidAdapter_spec.js +++ b/test/spec/modules/adhashBidAdapter_spec.js @@ -83,7 +83,7 @@ describe('adhashBidAdapter', function () { }; it('should build the request correctly', function () { const result = spec.buildRequests( - [ bidRequest ], + [bidRequest], { gdprConsent: { gdprApplies: true, consentString: 'example' }, refererInfo: { topmostLocation: 'https://example.com/path.html' } } ); expect(result.length).to.equal(1); @@ -101,7 +101,7 @@ describe('adhashBidAdapter', function () { expect(result[0].data).to.have.property('recentAds'); }); it('should build the request correctly without referer', function () { - const result = spec.buildRequests([ bidRequest ], { gdprConsent: { gdprApplies: true, consentString: 'example' } }); + const result = spec.buildRequests([bidRequest], { gdprConsent: { gdprApplies: true, consentString: 'example' } }); expect(result.length).to.equal(1); expect(result[0].method).to.equal('POST'); expect(result[0].url).to.equal('https://bidder.adhash.com/rtb?version=3.6&prebid=true&publisher=0xc3b09b27e9c6ef73957901aa729b9e69e5bbfbfb'); @@ -285,11 +285,11 @@ describe('adhashBidAdapter', function () { }); it('should return empty array when there are no creatives returned', function () { - expect(spec.interpretResponse({body: {creatives: []}}, request).length).to.equal(0); + expect(spec.interpretResponse({ body: { creatives: [] } }, request).length).to.equal(0); }); it('should return empty array when there is no creatives key in the response', function () { - expect(spec.interpretResponse({body: {}}, request).length).to.equal(0); + expect(spec.interpretResponse({ body: {} }, request).length).to.equal(0); }); it('should return empty array when something is not right', function () { diff --git a/test/spec/modules/adheseBidAdapter_spec.js b/test/spec/modules/adheseBidAdapter_spec.js index 4c16b774362..f608b9f0cb4 100644 --- a/test/spec/modules/adheseBidAdapter_spec.js +++ b/test/spec/modules/adheseBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adheseBidAdapter.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/adheseBidAdapter.js'; +import { config } from 'src/config.js'; const BID_ID = 456; const TTL = 360; @@ -72,68 +72,68 @@ describe('AdheseAdapter', function () { }; it('should include requested slots', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(JSON.parse(req.data).slots[0].slotname).to.equal('_main_page_-leaderboard'); }); it('should include all extra bid params', function () { - const req = spec.buildRequests([ bidWithParams({ 'ag': '25' }) ], bidderRequest); + const req = spec.buildRequests([bidWithParams({ 'ag': '25' })], bidderRequest); - expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ag': [ '25' ] }); + expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ag': ['25'] }); }); it('should assign bid params per slot', function () { - const req = spec.buildRequests([ bidWithParams({ 'ag': '25' }), bidWithParams({ 'ag': '25', 'ci': 'gent' }) ], bidderRequest); + const req = spec.buildRequests([bidWithParams({ 'ag': '25' }), bidWithParams({ 'ag': '25', 'ci': 'gent' })], bidderRequest); - expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ag': [ '25' ] }).and.not.to.deep.include({ 'ci': [ 'gent' ] }); - expect(JSON.parse(req.data).slots[1].parameters).to.deep.include({ 'ag': [ '25' ] }).and.to.deep.include({ 'ci': [ 'gent' ] }); + expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ag': ['25'] }).and.not.to.deep.include({ 'ci': ['gent'] }); + expect(JSON.parse(req.data).slots[1].parameters).to.deep.include({ 'ag': ['25'] }).and.to.deep.include({ 'ci': ['gent'] }); }); it('should split multiple target values', function () { - const req = spec.buildRequests([ bidWithParams({ 'ci': 'london' }), bidWithParams({ 'ci': 'gent' }) ], bidderRequest); + const req = spec.buildRequests([bidWithParams({ 'ci': 'london' }), bidWithParams({ 'ci': 'gent' })], bidderRequest); - expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ci': [ 'london' ] }); - expect(JSON.parse(req.data).slots[1].parameters).to.deep.include({ 'ci': [ 'gent' ] }); + expect(JSON.parse(req.data).slots[0].parameters).to.deep.include({ 'ci': ['london'] }); + expect(JSON.parse(req.data).slots[1].parameters).to.deep.include({ 'ci': ['gent'] }); }); it('should filter out empty params', function () { - const req = spec.buildRequests([ bidWithParams({ 'aa': [], 'bb': null, 'cc': '', 'dd': [ '', '' ], 'ee': [ 0, 1, null ], 'ff': 0, 'gg': [ 'x', 'y', '' ] }) ], bidderRequest); + const req = spec.buildRequests([bidWithParams({ 'aa': [], 'bb': null, 'cc': '', 'dd': ['', ''], 'ee': [0, 1, null], 'ff': 0, 'gg': ['x', 'y', ''] })], bidderRequest); const params = JSON.parse(req.data).slots[0].parameters; expect(params).to.not.have.any.keys('aa', 'bb', 'cc', 'dd'); - expect(params).to.deep.include({ 'ee': [ 0, 1 ], 'ff': [ 0 ], 'gg': [ 'x', 'y' ] }); + expect(params).to.deep.include({ 'ee': [0, 1], 'ff': [0], 'gg': ['x', 'y'] }); }); it('should include gdpr consent param', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); - expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': [ 'CONSENT_STRING' ] }); + expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': ['CONSENT_STRING'] }); }); it('should include referer param in base64url format', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); - expect(JSON.parse(req.data).parameters).to.deep.include({ 'xf': [ 'aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc3ViamVjdHM_X2Q9MQ' ] }); + expect(JSON.parse(req.data).parameters).to.deep.include({ 'xf': ['aHR0cDovL3ByZWJpZC5vcmcvZGV2LWRvY3Mvc3ViamVjdHM_X2Q9MQ'] }); }); it('should include eids', function () { const bid = minimalBid(); bid.userIdAsEids = [{ source: 'id5-sync.com', uids: [{ id: 'ID5@59sigaS-...' }] }]; - const req = spec.buildRequests([ bid ], bidderRequest); + const req = spec.buildRequests([bid], bidderRequest); expect(JSON.parse(req.data).user.ext.eids).to.deep.equal(bid.userIdAsEids); }); it('should not include eids field when userid module disabled', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(JSON.parse(req.data)).to.not.have.key('eids'); }); it('should request vast content as url by default', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(JSON.parse(req.data).vastContentAsUrl).to.equal(true); }); @@ -141,7 +141,7 @@ describe('AdheseAdapter', function () { it('should request vast content as markup when configured', function () { sinon.stub(config, 'getConfig').withArgs('adhese').returns({ vastContentAsUrl: false }); - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(JSON.parse(req.data).vastContentAsUrl).to.equal(false); config.getConfig.restore(); @@ -149,43 +149,43 @@ describe('AdheseAdapter', function () { it('should include bids', function () { const bid = minimalBid(); - const req = spec.buildRequests([ bid ], bidderRequest); + const req = spec.buildRequests([bid], bidderRequest); - expect(req.bids).to.deep.equal([ bid ]); + expect(req.bids).to.deep.equal([bid]); }); it('should make a POST request', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(req.method).to.equal('POST'); }); it('should request the json endpoint', function () { - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); expect(req.url).to.equal('https://ads-demo.adhese.com/json'); }); it('should include params specified in the config', function () { - sinon.stub(config, 'getConfig').withArgs('adhese').returns({ globalTargets: { 'tl': [ 'all' ] } }); - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + sinon.stub(config, 'getConfig').withArgs('adhese').returns({ globalTargets: { 'tl': ['all'] } }); + const req = spec.buildRequests([minimalBid()], bidderRequest); - expect(JSON.parse(req.data).parameters).to.deep.include({ 'tl': [ 'all' ] }); + expect(JSON.parse(req.data).parameters).to.deep.include({ 'tl': ['all'] }); config.getConfig.restore(); }); it('should give priority to bid params over config params', function () { sinon.stub(config, 'getConfig').withArgs('adhese').returns({ globalTargets: { 'xt': ['CONFIG_CONSENT_STRING'] } }); - const req = spec.buildRequests([ minimalBid() ], bidderRequest); + const req = spec.buildRequests([minimalBid()], bidderRequest); - expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': [ 'CONSENT_STRING' ] }); + expect(JSON.parse(req.data).parameters).to.deep.include({ 'xt': ['CONSENT_STRING'] }); config.getConfig.restore(); }); }); describe('interpretResponse', () => { const bidRequest = { - bids: [ minimalBid() ] + bids: [minimalBid()] }; it('should get correct ssp banner response', () => { @@ -212,7 +212,7 @@ describe('AdheseAdapter', function () { body: '
', tracker: 'https://hosts-demo.adhese.com/rtb_gateway/handlers/client/track/?id=a2f39296-6dd0-4b3c-be85-7baa22e7ff4a', impressionCounter: 'https://hosts-demo.adhese.com/rtb_gateway/handlers/client/track/?id=a2f39296-6dd0-4b3c-be85-7baa22e7ff4a', - extension: {'prebid': {'cpm': {'amount': '1.000000', 'currency': 'USD'}}, mediaType: 'banner'}, + extension: { 'prebid': { 'cpm': { 'amount': '1.000000', 'currency': 'USD' } }, mediaType: 'banner' }, adomain: [ 'www.example.com' ] @@ -239,7 +239,7 @@ describe('AdheseAdapter', function () { adType: 'leaderboard', seatbid: [ { - bid: [ { crid: '60613369', dealid: null } ], + bid: [{ crid: '60613369', dealid: null }], seat: '958' } ], @@ -267,7 +267,7 @@ describe('AdheseAdapter', function () { width: '640', height: '350', body: '', - extension: {'prebid': {'cpm': {'amount': '2.1', 'currency': 'USD'}}, mediaType: 'video'} + extension: { 'prebid': { 'cpm': { 'amount': '2.1', 'currency': 'USD' } }, mediaType: 'video' } } ] }; @@ -307,7 +307,7 @@ describe('AdheseAdapter', function () { width: '640', height: '350', cachedBodyUrl: 'https://ads-demo.adhese.com/content/38983ccc-4083-4c24-932c-96f798d969b3', - extension: {'prebid': {'cpm': {'amount': '2.1', 'currency': 'USD'}}, mediaType: 'video'} + extension: { 'prebid': { 'cpm': { 'amount': '2.1', 'currency': 'USD' } }, mediaType: 'video' } } ] }; diff --git a/test/spec/modules/adipoloBidAdapter_spec.js b/test/spec/modules/adipoloBidAdapter_spec.js index 823244ab758..31f08a09007 100644 --- a/test/spec/modules/adipoloBidAdapter_spec.js +++ b/test/spec/modules/adipoloBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/adipoloBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/adipoloBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; import sinon from 'sinon'; const US_ENDPOINT = 'https://prebid.adipolo.live'; @@ -50,12 +50,12 @@ defaultRequestVideo.mediaTypes = { const videoBidderRequest = { bidderCode: 'adipolo', - bids: [{mediaTypes: {video: {}}, bidId: 'qwerty'}] + bids: [{ mediaTypes: { video: {} }, bidId: 'qwerty' }] }; const displayBidderRequest = { bidderCode: 'adipolo', - bids: [{bidId: 'qwerty'}] + bids: [{ bidId: 'qwerty' }] }; describe('adipoloBidAdapter', () => { @@ -139,7 +139,7 @@ describe('adipoloBidAdapter', () => { expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); expect(request).to.have.property('floor').and.to.equal(null); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -231,7 +231,7 @@ describe('adipoloBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -247,8 +247,8 @@ describe('adipoloBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -300,7 +300,7 @@ describe('adipoloBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -309,7 +309,7 @@ describe('adipoloBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['adipolo']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['adipolo'] }); }); it('should interpret valid banner response', function () { @@ -330,7 +330,7 @@ describe('adipoloBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -356,7 +356,7 @@ describe('adipoloBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: videoBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: videoBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -372,12 +372,12 @@ describe('adipoloBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -396,7 +396,7 @@ describe('adipoloBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -415,7 +415,7 @@ describe('adipoloBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -439,20 +439,20 @@ describe('adipoloBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -460,7 +460,7 @@ describe('adipoloBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -468,7 +468,7 @@ describe('adipoloBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/adkernelAdnAnalytics_spec.js b/test/spec/modules/adkernelAdnAnalytics_spec.js index 95d01f53b2b..41477c55588 100644 --- a/test/spec/modules/adkernelAdnAnalytics_spec.js +++ b/test/spec/modules/adkernelAdnAnalytics_spec.js @@ -1,5 +1,5 @@ -import analyticsAdapter, {ExpiringQueue, getUmtSource, storage} from 'modules/adkernelAdnAnalyticsAdapter'; -import {expect} from 'chai'; +import analyticsAdapter, { ExpiringQueue, getUmtSource, storage } from 'modules/adkernelAdnAnalyticsAdapter'; +import { expect } from 'chai'; import adapterManager from 'src/adapterManager'; import { EVENTS } from 'src/constants.js'; @@ -231,17 +231,17 @@ describe('', function () { }); it('should handle auction init event', function () { - events.emit(EVENTS.AUCTION_INIT, {config: {}, bidderRequests: [REQUEST], timeout: 3000}); + events.emit(EVENTS.AUCTION_INIT, { config: {}, bidderRequests: [REQUEST], timeout: 3000 }); const ev = analyticsAdapter.context.queue.peekAll(); expect(ev).to.have.length(1); - expect(ev[0]).to.be.eql({event: 'auctionInit'}); + expect(ev[0]).to.be.eql({ event: 'auctionInit' }); }); it('should handle bid request event', function () { events.emit(EVENTS.BID_REQUESTED, REQUEST); const ev = analyticsAdapter.context.queue.peekAll(); expect(ev).to.have.length(2); - expect(ev[1]).to.be.eql({event: 'bidRequested', adapter: 'adapter', tagid: 'container-1'}); + expect(ev[1]).to.be.eql({ event: 'bidRequested', adapter: 'adapter', tagid: 'container-1' }); }); it('should handle bid response event', function () { @@ -264,7 +264,7 @@ describe('', function () { expect(ev).to.have.length(0); expect(ajaxStub.calledOnce).to.be.equal(true); ev = JSON.parse(ajaxStub.firstCall.args[0]).hb_ev; - expect(ev[3]).to.be.eql({event: 'auctionEnd', time: 0.447}); + expect(ev[3]).to.be.eql({ event: 'auctionEnd', time: 0.447 }); }); it('should handle winning bid', function () { @@ -272,7 +272,7 @@ describe('', function () { timer.tick(4500); expect(ajaxStub.calledTwice).to.be.equal(true); const ev = JSON.parse(ajaxStub.secondCall.args[0]).hb_ev; - expect(ev[0]).to.be.eql({event: 'bidWon', adapter: 'adapter', tagid: 'container-1', val: 0.015}); + expect(ev[0]).to.be.eql({ event: 'bidWon', adapter: 'adapter', tagid: 'container-1', val: 0.015 }); }); }); }); diff --git a/test/spec/modules/adkernelAdnBidAdapter_spec.js b/test/spec/modules/adkernelAdnBidAdapter_spec.js index 2618d5f8ddb..875f4b6e42a 100644 --- a/test/spec/modules/adkernelAdnBidAdapter_spec.js +++ b/test/spec/modules/adkernelAdnBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adkernelAdnBidAdapter'; -import {config} from 'src/config'; +import { expect } from 'chai'; +import { spec } from 'modules/adkernelAdnBidAdapter'; +import { config } from 'src/config'; describe('AdkernelAdn adapter', function () { const bid1_pub1 = { @@ -92,11 +92,11 @@ describe('AdkernelAdn adapter', function () { auctionId: 'auc-001', bidId: 'Bid_01', mediaTypes: { - banner: {sizes: [[300, 250], [300, 200]]}, - video: {context: 'instream', playerSize: [[640, 480]]} + banner: { sizes: [[300, 250], [300, 200]] }, + video: { context: 'instream', playerSize: [[640, 480]] } }, adUnitCode: 'ad-unit-1', - params: {pubId: 7} + params: { pubId: 7 } }; const response = { @@ -220,7 +220,7 @@ describe('AdkernelAdn adapter', function () { } describe('banner request building', function () { - const [_, tagRequests] = buildRequest([bid1_pub1], {ortb2: {source: {tid: 'mock-tid'}}}); + const [_, tagRequests] = buildRequest([bid1_pub1], { ortb2: { source: { tid: 'mock-tid' } } }); const tagRequest = tagRequests[0]; it('should have request id', function () { @@ -260,7 +260,7 @@ describe('AdkernelAdn adapter', function () { it('should contain gdpr and ccpa information if consent is configured', function () { const [_, bidRequests] = buildRequest([bid1_pub1], - {gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}, uspConsent: '1YNN'}); + { gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' }, uspConsent: '1YNN' }); expect(bidRequests[0]).to.have.property('user'); expect(bidRequests[0].user).to.have.property('gdpr', 1); expect(bidRequests[0].user).to.have.property('consent', 'test-consent-string'); @@ -268,14 +268,14 @@ describe('AdkernelAdn adapter', function () { }); it('should\'t contain consent string if gdpr isn\'t applied', function () { - const [_, bidRequests] = buildRequest([bid1_pub1], {gdprConsent: {gdprApplies: false}}); + const [_, bidRequests] = buildRequest([bid1_pub1], { gdprConsent: { gdprApplies: false } }); expect(bidRequests[0]).to.have.property('user'); expect(bidRequests[0].user).to.have.property('gdpr', 0); expect(bidRequests[0].user).to.not.have.property('consent'); }); it('should\'t contain consent string if gdpr isn\'t applied', function () { - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const [_, bidRequests] = buildRequest([bid1_pub1]); config.resetConfig(); expect(bidRequests[0]).to.have.property('user'); @@ -365,7 +365,7 @@ describe('AdkernelAdn adapter', function () { let responses; before(function () { - responses = spec.interpretResponse({body: response}); + responses = spec.interpretResponse({ body: response }); }); it('should parse all responses', function () { @@ -404,9 +404,9 @@ describe('AdkernelAdn adapter', function () { }); it('should perform usersync', function () { - let syncs = spec.getUserSyncs({iframeEnabled: false}, [{body: response}]); + let syncs = spec.getUserSyncs({ iframeEnabled: false }, [{ body: response }]); expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: response}]); + syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: response }]); expect(syncs).to.have.length(1); expect(syncs[0]).to.have.property('type', 'iframe'); expect(syncs[0]).to.have.property('url', 'https://dsp.adkernel.com/sync'); @@ -414,12 +414,12 @@ describe('AdkernelAdn adapter', function () { it('should handle user-sync only response', function () { const [pbRequests, tagRequests] = buildRequest([bid1_pub1]); - const resp = spec.interpretResponse({body: usersyncOnlyResponse}, pbRequests[0]); + const resp = spec.interpretResponse({ body: usersyncOnlyResponse }, pbRequests[0]); expect(resp).to.have.length(0); }); it('shouldn\' fail on empty response', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}, [{body: ''}]); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [{ body: '' }]); expect(syncs).to.have.length(0); }); }); diff --git a/test/spec/modules/adkernelBidAdapter_spec.js b/test/spec/modules/adkernelBidAdapter_spec.js index b2ca5c622fe..917b39a8eb4 100644 --- a/test/spec/modules/adkernelBidAdapter_spec.js +++ b/test/spec/modules/adkernelBidAdapter_spec.js @@ -1,15 +1,15 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adkernelBidAdapter'; +import { expect } from 'chai'; +import { spec } from 'modules/adkernelBidAdapter'; import * as utils from 'src/utils'; import * as navigatorDnt from 'libraries/dnt/index.js'; -import {NATIVE, BANNER, VIDEO} from 'src/mediaTypes'; -import {config} from 'src/config'; -import {parseDomain} from '../../../src/refererDetection.js'; +import { NATIVE, BANNER, VIDEO } from 'src/mediaTypes'; +import { config } from 'src/config'; +import { parseDomain } from '../../../src/refererDetection.js'; describe('Adkernel adapter', function () { const bid1_zone1 = { bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, + params: { zoneId: 1, host: 'rtb.adkernel.com' }, adUnitCode: 'ad-unit-1', bidId: 'Bid_01', bidderRequestId: 'req-001', @@ -26,7 +26,7 @@ describe('Adkernel adapter', function () { } }; const bid2_zone2 = { bidder: 'adkernel', - params: {zoneId: 2, host: 'rtb.adkernel.com'}, + params: { zoneId: 2, host: 'rtb.adkernel.com' }, adUnitCode: 'ad-unit-2', bidId: 'Bid_02', bidderRequestId: 'req-001', @@ -40,13 +40,13 @@ describe('Adkernel adapter', function () { { source: 'crwdcntrl.net', uids: [ - {atype: 1, id: '97d09fbba28542b7acbb6317c9534945a702b74c5993c352f332cfe83f40cdd9'} + { atype: 1, id: '97d09fbba28542b7acbb6317c9534945a702b74c5993c352f332cfe83f40cdd9' } ] } ] }; const bid3_host2 = { bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb-private.adkernel.com'}, + params: { zoneId: 1, host: 'rtb-private.adkernel.com' }, adUnitCode: 'ad-unit-2', bidId: 'Bid_02', bidderRequestId: 'req-001', @@ -58,7 +58,7 @@ describe('Adkernel adapter', function () { } }; const bid_without_zone = { bidder: 'adkernel', - params: {host: 'rtb-private.adkernel.com'}, + params: { host: 'rtb-private.adkernel.com' }, adUnitCode: 'ad-unit-1', bidId: 'Bid_W', bidderRequestId: 'req-002', @@ -70,7 +70,7 @@ describe('Adkernel adapter', function () { } }; const bid_without_host = { bidder: 'adkernel', - params: {zoneId: 1}, + params: { zoneId: 1 }, adUnitCode: 'ad-unit-1', bidId: 'Bid_W', bidderRequestId: 'req-002', @@ -82,7 +82,7 @@ describe('Adkernel adapter', function () { } }; const bid_with_wrong_zoneId = { bidder: 'adkernel', - params: {zoneId: 'wrong id', host: 'rtb.adkernel.com'}, + params: { zoneId: 'wrong id', host: 'rtb.adkernel.com' }, adUnitCode: 'ad-unit-2', bidId: 'Bid_02', bidderRequestId: 'req-002', @@ -116,10 +116,10 @@ describe('Adkernel adapter', function () { adUnitCode: 'ad-unit-1' }; const bid_multiformat = { bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, + params: { zoneId: 1, host: 'rtb.adkernel.com' }, mediaTypes: { - banner: {sizes: [[300, 250], [300, 200]]}, - video: {context: 'instream', playerSize: [[640, 480]]} + banner: { sizes: [[300, 250], [300, 200]] }, + video: { context: 'instream', playerSize: [[640, 480]] } }, adUnitCode: 'ad-unit-1', transactionId: 'f82c64b8-c602-42a4-9791-4a268f6559ed', @@ -129,7 +129,7 @@ describe('Adkernel adapter', function () { }; const bid_native = { bidder: 'adkernel', - params: {zoneId: 1, host: 'rtb.adkernel.com'}, + params: { zoneId: 1, host: 'rtb.adkernel.com' }, mediaTypes: { native: { title: { @@ -144,7 +144,7 @@ describe('Adkernel adapter', function () { }, icon: { required: true, - aspect_ratios: [{min_width: 50, min_height: 50}] + aspect_ratios: [{ min_width: 50, min_height: 50 }] }, image: { required: true, @@ -177,25 +177,24 @@ describe('Adkernel adapter', function () { ver: '1.2', assets: [ { - id: 0, required: 1, title: {len: 80} - }, { - id: 1, required: 1, data: {type: 2}}, + id: 0, required: 1, title: { len: 80 } + }, { id: 1, required: 1, data: { type: 2 } }, { - id: 2, required: 1, data: {type: 10} + id: 2, required: 1, data: { type: 10 } }, { - id: 3, required: 1, img: {type: 1, wmin: 50, hmin: 50} + id: 3, required: 1, img: { type: 1, wmin: 50, hmin: 50 } }, { - id: 4, required: 1, img: {type: 3, w: 300, h: 200} + id: 4, required: 1, img: { type: 3, w: 300, h: 200 } }, { - id: 5, required: 0, data: {type: 3} + id: 5, required: 0, data: { type: 3 } }, { - id: 6, required: 0, data: {type: 6} + id: 6, required: 0, data: { type: 6 } }, { - id: 7, required: 0, data: {type: 12} + id: 7, required: 0, data: { type: 12 } }, { - id: 8, required: 0, data: {type: 1} + id: 8, required: 0, data: { type: 1 } }, { - id: 9, required: 0, data: {type: 11} + id: 9, required: 0, data: { type: 11 } } ], privacy: 1 @@ -224,7 +223,7 @@ describe('Adkernel adapter', function () { }] }], ext: { - adk_usersync: [{type: 1, url: 'https://adk.sync.com/sync'}] + adk_usersync: [{ type: 1, url: 'https://adk.sync.com/sync' }] } }; const videoBidResponse = { id: '47ce4badcf7482', @@ -259,7 +258,7 @@ describe('Adkernel adapter', function () { const usersyncOnlyResponse = { id: 'nobid1', ext: { - adk_usersync: [{type: 2, url: 'https://adk.sync.com/sync'}] + adk_usersync: [{ type: 2, url: 'https://adk.sync.com/sync' }] } }; const nativeResponse = { id: '56fbc713-b737-4651-9050-13376aed9818', @@ -272,15 +271,15 @@ describe('Adkernel adapter', function () { adm: JSON.stringify({ native: { assets: [ - {id: 0, title: {text: 'Title'}}, - {id: 3, data: {value: 'Description'}}, - {id: 4, data: {value: 'Additional description'}}, - {id: 1, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', w: 50, h: 50}}, - {id: 2, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', w: 300, h: 200}}, - {id: 5, data: {value: 'Sponsor.com'}}, - {id: 14, data: {value: 'displayurl.com'}} + { id: 0, title: { text: 'Title' } }, + { id: 3, data: { value: 'Description' } }, + { id: 4, data: { value: 'Additional description' } }, + { id: 1, img: { url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', w: 50, h: 50 } }, + { id: 2, img: { url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', w: 300, h: 200 } }, + { id: 5, data: { value: 'Sponsor.com' } }, + { id: 14, data: { value: 'displayurl.com' } } ], - link: {url: 'http://rtb.com/click?i=pTuOlf5KHUo_0'}, + link: { url: 'http://rtb.com/click?i=pTuOlf5KHUo_0' }, imptrackers: ['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp'] } }), @@ -338,7 +337,7 @@ describe('Adkernel adapter', function () { }); function buildBidderRequest(url = 'https://example.com/index.html', params = {}) { - return Object.assign({}, params, {refererInfo: {page: url, domain: parseDomain(url), reachedTop: true}, timeout: 3000, bidderCode: 'adkernel'}); + return Object.assign({}, params, { refererInfo: { page: url, domain: parseDomain(url), reachedTop: true }, timeout: 3000, bidderCode: 'adkernel' }); } const DEFAULT_BIDDER_REQUEST = buildBidderRequest(); @@ -398,7 +397,7 @@ describe('Adkernel adapter', function () { it('should have w/h', function () { expect(bidRequest.imp[0].banner).to.have.property('format'); - expect(bidRequest.imp[0].banner.format).to.be.eql([{w: 300, h: 250}, {w: 300, h: 200}]); + expect(bidRequest.imp[0].banner.format).to.be.eql([{ w: 300, h: 250 }, { w: 300, h: 200 }]); }); it('should respect secure connection', function () { @@ -441,21 +440,22 @@ describe('Adkernel adapter', function () { it('should contain gdpr-related information if consent is configured', function () { const [_, bidRequests] = buildRequest([bid1_zone1], buildBidderRequest('https://example.com/index.html', { - gdprConsent: {gdprApplies: true, consentString: 'test-consent-string', vendorData: {}}, + gdprConsent: { gdprApplies: true, consentString: 'test-consent-string', vendorData: {} }, uspConsent: '1YNN', - gppConsent: {gppString: 'DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', applicableSections: [2]}} + gppConsent: { gppString: 'DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', applicableSections: [2] } + } )); const bidRequest = bidRequests[0]; expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs.ext).to.be.eql({'gdpr': 1, 'us_privacy': '1YNN'}); + expect(bidRequest.regs.ext).to.be.eql({ 'gdpr': 1, 'us_privacy': '1YNN' }); expect(bidRequest.regs.gpp).to.be.eql('DBABMA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA'); expect(bidRequest.regs.gpp_sid).to.be.eql([2]); expect(bidRequest).to.have.property('user'); - expect(bidRequest.user.ext).to.be.eql({'consent': 'test-consent-string'}); + expect(bidRequest.user.ext).to.be.eql({ 'consent': 'test-consent-string' }); }); it('should contain coppa if configured', function () { - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const [_, bidRequests] = buildRequest([bid1_zone1]); const bidRequest = bidRequests[0]; expect(bidRequest).to.have.property('regs'); @@ -463,10 +463,10 @@ describe('Adkernel adapter', function () { }); it('should\'t contain consent string if gdpr isn\'t applied', function () { - const [_, bidRequests] = buildRequest([bid1_zone1], buildBidderRequest('https://example.com/index.html', {gdprConsent: {gdprApplies: false}})); + const [_, bidRequests] = buildRequest([bid1_zone1], buildBidderRequest('https://example.com/index.html', { gdprConsent: { gdprApplies: false } })); const bidRequest = bidRequests[0]; expect(bidRequest).to.have.property('regs'); - expect(bidRequest.regs.ext).to.be.eql({'gdpr': 0}); + expect(bidRequest.regs.ext).to.be.eql({ 'gdpr': 0 }); expect(bidRequest).to.not.have.property('user'); }); @@ -552,7 +552,7 @@ describe('Adkernel adapter', function () { expect(bidRequests[0].imp[1].id).to.be.not.eql(bidRequests[0].imp[0].id); }); it('should collect ads back to same requestId', function() { - const bids = spec.interpretResponse({body: multiformat_response}, pbRequests[0]); + const bids = spec.interpretResponse({ body: multiformat_response }, pbRequests[0]); expect(bids).to.have.length(2); expect(bids[0].requestId).to.be.eql('Bid_01'); expect(bids[0].mediaType).to.be.eql('banner'); @@ -658,7 +658,7 @@ describe('Adkernel adapter', function () { describe('responses processing', function () { it('should return fully-initialized banner bid-response', function () { const [pbRequests, _] = buildRequest([bid1_zone1]); - const resp = spec.interpretResponse({body: bannerBidResponse}, pbRequests[0])[0]; + const resp = spec.interpretResponse({ body: bannerBidResponse }, pbRequests[0])[0]; expect(resp).to.have.property('requestId', 'Bid_01'); expect(resp).to.have.property('cpm', 3.01); expect(resp).to.have.property('width', 300); @@ -675,7 +675,7 @@ describe('Adkernel adapter', function () { it('should return fully-initialized video bid-response', function () { const [pbRequests, _] = buildRequest([bid_video]); - const resp = spec.interpretResponse({body: videoBidResponse}, pbRequests[0])[0]; + const resp = spec.interpretResponse({ body: videoBidResponse }, pbRequests[0])[0]; expect(resp).to.have.property('requestId', 'Bid_Video'); expect(resp.mediaType).to.equal(VIDEO); expect(resp.cpm).to.equal(0.00145); @@ -686,7 +686,7 @@ describe('Adkernel adapter', function () { it('should support vast xml in adm', function () { const [pbRequests, _] = buildRequest([bid_video]); - const resp = spec.interpretResponse({body: videoBidResponseWithAdm}, pbRequests[0])[0]; + const resp = spec.interpretResponse({ body: videoBidResponseWithAdm }, pbRequests[0])[0]; expect(resp).to.have.property('requestId', 'Bid_Video'); expect(resp.mediaType).to.equal(VIDEO); expect(resp.cpm).to.equal(0.00145); @@ -698,27 +698,27 @@ describe('Adkernel adapter', function () { it('should add nurl as pixel for banner response', function () { const [pbRequests, _] = buildRequest([bid1_zone1]); - const resp = spec.interpretResponse({body: bannerBidResponse}, pbRequests[0])[0]; + const resp = spec.interpretResponse({ body: bannerBidResponse }, pbRequests[0])[0]; const expectedNurl = bannerBidResponse.seatbid[0].bid[0].nurl + '&px=1'; expect(resp.ad).to.have.string(expectedNurl); }); it('should handle bidresponse with user-sync only', function () { const [pbRequests, _] = buildRequest([bid1_zone1]); - const resp = spec.interpretResponse({body: usersyncOnlyResponse}, pbRequests[0]); + const resp = spec.interpretResponse({ body: usersyncOnlyResponse }, pbRequests[0]); expect(resp).to.have.length(0); }); it('should perform usersync', function () { - let syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, []); + let syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, []); expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, [{body: bannerBidResponse}]); + syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }, [{ body: bannerBidResponse }]); expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [{body: bannerBidResponse}]); + syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [{ body: bannerBidResponse }]); expect(syncs).to.have.length(1); expect(syncs[0]).to.have.property('type', 'iframe'); expect(syncs[0]).to.have.property('url', 'https://adk.sync.com/sync'); - syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{body: usersyncOnlyResponse}]); + syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: usersyncOnlyResponse }]); expect(syncs).to.have.length(1); expect(syncs[0]).to.have.property('type', 'image'); expect(syncs[0]).to.have.property('url', 'https://adk.sync.com/sync'); @@ -744,21 +744,21 @@ describe('Adkernel adapter', function () { const request = JSON.parse(bidRequests[0].imp[0].native.request); expect(request).to.have.property('ver', '1.2'); expect(request.assets).to.have.length(10); - expect(request.assets[0]).to.be.eql({id: 0, required: 1, title: {len: 80}}); - expect(request.assets[1]).to.be.eql({id: 1, required: 1, data: {type: 2}}); - expect(request.assets[2]).to.be.eql({id: 2, required: 1, data: {type: 10}}); - expect(request.assets[3]).to.be.eql({id: 3, required: 1, img: {wmin: 50, hmin: 50, type: 1}}); - expect(request.assets[4]).to.be.eql({id: 4, required: 1, img: {w: 300, h: 200, type: 3}}); - expect(request.assets[5]).to.be.eql({id: 5, required: 0, data: {type: 3}}); - expect(request.assets[6]).to.be.eql({id: 6, required: 0, data: {type: 6}}); - expect(request.assets[7]).to.be.eql({id: 7, required: 0, data: {type: 12}}); - expect(request.assets[8]).to.be.eql({id: 8, required: 0, data: {type: 1}}); - expect(request.assets[9]).to.be.eql({id: 9, required: 0, data: {type: 11}}); + expect(request.assets[0]).to.be.eql({ id: 0, required: 1, title: { len: 80 } }); + expect(request.assets[1]).to.be.eql({ id: 1, required: 1, data: { type: 2 } }); + expect(request.assets[2]).to.be.eql({ id: 2, required: 1, data: { type: 10 } }); + expect(request.assets[3]).to.be.eql({ id: 3, required: 1, img: { wmin: 50, hmin: 50, type: 1 } }); + expect(request.assets[4]).to.be.eql({ id: 4, required: 1, img: { w: 300, h: 200, type: 3 } }); + expect(request.assets[5]).to.be.eql({ id: 5, required: 0, data: { type: 3 } }); + expect(request.assets[6]).to.be.eql({ id: 6, required: 0, data: { type: 6 } }); + expect(request.assets[7]).to.be.eql({ id: 7, required: 0, data: { type: 12 } }); + expect(request.assets[8]).to.be.eql({ id: 8, required: 0, data: { type: 1 } }); + expect(request.assets[9]).to.be.eql({ id: 9, required: 0, data: { type: 11 } }); }); it('native response processing', () => { const [pbRequests, _] = buildRequest([bid_native]); - const resp = spec.interpretResponse({body: nativeResponse}, pbRequests[0])[0]; + const resp = spec.interpretResponse({ body: nativeResponse }, pbRequests[0])[0]; expect(resp).to.have.property('requestId', 'Bid_01'); expect(resp).to.have.property('cpm', 2.25); expect(resp).to.have.property('currency', 'EUR'); @@ -774,15 +774,15 @@ describe('Adkernel adapter', function () { expect(resp.native.ortb).to.be.eql({ assets: [ - {id: 0, title: {text: 'Title'}}, - {id: 3, data: {value: 'Description'}}, - {id: 4, data: {value: 'Additional description'}}, - {id: 1, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', w: 50, h: 50}}, - {id: 2, img: {url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', w: 300, h: 200}}, - {id: 5, data: {value: 'Sponsor.com'}}, - {id: 14, data: {value: 'displayurl.com'}} + { id: 0, title: { text: 'Title' } }, + { id: 3, data: { value: 'Description' } }, + { id: 4, data: { value: 'Additional description' } }, + { id: 1, img: { url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0&imgt=icon', w: 50, h: 50 } }, + { id: 2, img: { url: 'http://rtb.com/thumbnail?i=pTuOlf5KHUo_0', w: 300, h: 200 } }, + { id: 5, data: { value: 'Sponsor.com' } }, + { id: 14, data: { value: 'displayurl.com' } } ], - link: {url: 'http://rtb.com/click?i=pTuOlf5KHUo_0'}, + link: { url: 'http://rtb.com/click?i=pTuOlf5KHUo_0' }, imptrackers: ['http://rtb.com/win?i=pTuOlf5KHUo_0&f=imp'] }); }); @@ -797,7 +797,7 @@ describe('Adkernel adapter', function () { }); it('should trigger pixel for nurl', () => { const [pbRequests, _] = buildRequest([bid_video]); - const bid = spec.interpretResponse({body: videoBidResponseWithAdm}, pbRequests[0])[0]; + const bid = spec.interpretResponse({ body: videoBidResponseWithAdm }, pbRequests[0])[0]; spec.onBidWon(bid); expect(utils.triggerPixel.callCount).to.equal(1); }); diff --git a/test/spec/modules/adlaneRtdProvider_spec.js b/test/spec/modules/adlaneRtdProvider_spec.js index 43f7790ce57..cdb27101859 100644 --- a/test/spec/modules/adlaneRtdProvider_spec.js +++ b/test/spec/modules/adlaneRtdProvider_spec.js @@ -10,7 +10,7 @@ import { import * as utils from 'src/utils.js'; import * as storageManager from 'src/storageManager.js'; import { config } from 'src/config.js'; -import {init} from 'modules/rtdModule' +import { init } from 'modules/rtdModule' describe('adlane Module', () => { let sandbox; diff --git a/test/spec/modules/adlooxAdServerVideo_spec.js b/test/spec/modules/adlooxAdServerVideo_spec.js index 6469f72e59a..5349cd69dc2 100644 --- a/test/spec/modules/adlooxAdServerVideo_spec.js +++ b/test/spec/modules/adlooxAdServerVideo_spec.js @@ -5,7 +5,7 @@ import { expect } from 'chai'; import * as events from 'src/events.js'; import { targeting } from 'src/targeting.js'; import * as utils from 'src/utils.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; const analyticsAdapterName = 'adloox'; @@ -17,7 +17,7 @@ describe('Adloox Ad Server Video', function () { mediaTypes: { video: { context: 'instream', - playerSize: [ 640, 480 ] + playerSize: [640, 480] } }, bids: [ @@ -156,7 +156,7 @@ describe('Adloox Ad Server Video', function () { const BID = utils.deepClone(bid); const getWinningBidsStub = sinon.stub(targeting, 'getWinningBids') - getWinningBidsStub.withArgs(adUnit.code).returns([ BID ]); + getWinningBidsStub.withArgs(adUnit.code).returns([BID]); const ret = buildVideoUrl({ url: vastUrl }, function () {}); expect(ret).is.false; @@ -203,7 +203,7 @@ describe('Adloox Ad Server Video', function () { beforeEach(function () { BID = utils.deepClone(bid); getWinningBidsStub = sinon.stub(targeting, 'getWinningBids') - getWinningBidsStub.withArgs(adUnit.code).returns([ BID ]); + getWinningBidsStub.withArgs(adUnit.code).returns([BID]); }); afterEach(function () { getWinningBidsStub.restore(); diff --git a/test/spec/modules/adlooxAnalyticsAdapter_spec.js b/test/spec/modules/adlooxAnalyticsAdapter_spec.js index ede92f5934e..30404fc9dc6 100644 --- a/test/spec/modules/adlooxAnalyticsAdapter_spec.js +++ b/test/spec/modules/adlooxAnalyticsAdapter_spec.js @@ -112,7 +112,7 @@ describe('Adloox Analytics Adapter', function () { done(); }); - [ 'client', 'clientid', 'platformid', 'tagid' ].forEach(function (o) { + ['client', 'clientid', 'platformid', 'tagid'].forEach(function (o) { it('should require options.' + o, function (done) { const analyticsOptionsLocal = utils.deepClone(analyticsOptions); delete analyticsOptionsLocal[o]; @@ -253,7 +253,7 @@ describe('Adloox Analytics Adapter', function () { const data = { url: 'https://example.com?', args: [ - [ 'client', '%%client%%' ] + ['client', '%%client%%'] ], bid: bid, ids: true diff --git a/test/spec/modules/adlooxRtdProvider_spec.js b/test/spec/modules/adlooxRtdProvider_spec.js index 0fb0da58c1a..783b6ad6ca8 100644 --- a/test/spec/modules/adlooxRtdProvider_spec.js +++ b/test/spec/modules/adlooxRtdProvider_spec.js @@ -1,12 +1,12 @@ import adapterManager from 'src/adapterManager.js'; import analyticsAdapter from 'modules/adlooxAnalyticsAdapter.js'; -import {auctionManager} from 'src/auctionManager.js'; +import { auctionManager } from 'src/auctionManager.js'; import { expect } from 'chai'; import * as events from 'src/events.js'; import * as prebidGlobal from 'src/prebidGlobal.js'; import { subModuleObj as rtdProvider } from 'modules/adlooxRtdProvider.js'; import * as utils from 'src/utils.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; const analyticsAdapterName = 'adloox'; @@ -24,7 +24,7 @@ describe('Adloox RTD Provider', function () { }, mediaTypes: { banner: { - sizes: [ [300, 250] ] + sizes: [[300, 250]] } }, bids: [ @@ -101,7 +101,7 @@ describe('Adloox RTD Provider', function () { }); it('should reject non-array of integers with value greater than zero config.params.thresholds', function (done) { - const ret = rtdProvider.init({ params: { thresholds: [ 70, null ] } }); + const ret = rtdProvider.init({ params: { thresholds: [70, null] } }); expect(ret).is.false; @@ -149,7 +149,7 @@ describe('Adloox RTD Provider', function () { it('should fetch segments', function (done) { const req = { - adUnitCodes: [ adUnit.code ], + adUnitCodes: [adUnit.code], ortb2Fragments: { global: { site: { @@ -169,7 +169,7 @@ describe('Adloox RTD Provider', function () { }; const adUnitWithSegments = utils.deepClone(adUnit); const getGlobalStub = sinon.stub(prebidGlobal, 'getGlobal').returns({ - adUnits: [ adUnitWithSegments ] + adUnits: [adUnitWithSegments] }); const ret = rtdProvider.init(CONFIG); @@ -191,24 +191,24 @@ describe('Adloox RTD Provider', function () { rtdProvider.getBidRequestData(req, callback, CONFIG, null); const request = server.requests[0]; - const response = { unused: false, _: [ { d: 77 } ] }; + const response = { unused: false, _: [{ d: 77 }] }; request.respond(200, { 'content-type': 'application/json' }, JSON.stringify(response)); }); it('should set ad server targeting', function (done) { const adUnitWithSegments = utils.deepClone(adUnit); - utils.deepSetValue(adUnitWithSegments, 'ortb2Imp.ext.data.adloox_rtd.dis', [ 50, 60 ]); + utils.deepSetValue(adUnitWithSegments, 'ortb2Imp.ext.data.adloox_rtd.dis', [50, 60]); const getGlobalStub = sinon.stub(prebidGlobal, 'getGlobal').returns({ - adUnits: [ adUnitWithSegments ] + adUnits: [adUnitWithSegments] }); - const auction = { adUnits: [ adUnitWithSegments ] }; + const auction = { adUnits: [adUnitWithSegments] }; const getAuctionStub = sinon.stub(auctionManager.index, 'getAuction').returns({ - adUnits: [ adUnitWithSegments ], + adUnits: [adUnitWithSegments], getFPD: () => { return { global: { site: { ext: { data: { adloox_rtd: { ok: true } } } } } } } }); - const targetingData = rtdProvider.getTargetingData([ adUnitWithSegments.code ], CONFIG, null, auction); + const targetingData = rtdProvider.getTargetingData([adUnitWithSegments.code], CONFIG, null, auction); expect(Object.keys(targetingData).length).is.equal(1); expect(Object.keys(targetingData[adUnit.code]).length).is.equal(2); expect(targetingData[adUnit.code].adl_ok).is.equal(1); diff --git a/test/spec/modules/admaticBidAdapter_spec.js b/test/spec/modules/admaticBidAdapter_spec.js index 1fce6a179be..a16fd665f9c 100644 --- a/test/spec/modules/admaticBidAdapter_spec.js +++ b/test/spec/modules/admaticBidAdapter_spec.js @@ -7,7 +7,7 @@ const ENDPOINT = 'https://layer.rtb.admatic.com.tr/pb'; describe('admaticBidAdapter', () => { const adapter = newBidder(spec); - const validRequest = [ { + const validRequest = [{ 'refererInfo': { 'page': 'https://www.admatic.com.tr', 'domain': 'https://www.admatic.com.tr', @@ -241,7 +241,7 @@ describe('admaticBidAdapter', () => { 'cur': 'USD', 'bidder': 'admatic' } - } ]; + }]; const bidderRequest = { 'refererInfo': { 'page': 'https://www.admatic.com.tr', @@ -795,64 +795,66 @@ describe('admaticBidAdapter', () => { describe('interpretResponse', function () { it('should get correct bid responses', function() { - const bids = { body: { - data: [ - { - 'id': 1, - 'creative_id': '374', - 'width': 300, - 'height': 250, - 'price': 0.01, - 'type': 'banner', - 'bidder': 'admatic', - 'currency': 'TRY', - 'mime_type': { - 'name': 'backfill', - 'force': false - }, - 'adomain': ['admatic.com.tr'], - 'party_tag': '
', - 'iurl': 'https://www.admatic.com.tr' - }, - { - 'id': 2, - 'creative_id': '3741', - 'width': 300, - 'height': 250, - 'price': 0.01, - 'currency': 'TRY', - 'type': 'video', - 'mime_type': { - 'name': 'backfill', - 'force': false + const bids = { + body: { + data: [ + { + 'id': 1, + 'creative_id': '374', + 'width': 300, + 'height': 250, + 'price': 0.01, + 'type': 'banner', + 'bidder': 'admatic', + 'currency': 'TRY', + 'mime_type': { + 'name': 'backfill', + 'force': false + }, + 'adomain': ['admatic.com.tr'], + 'party_tag': '
', + 'iurl': 'https://www.admatic.com.tr' }, - 'bidder': 'admatic', - 'adomain': ['admatic.com.tr'], - 'party_tag': '', - 'iurl': 'https://www.admatic.com.tr' - }, - { - 'id': 3, - 'creative_id': '3742', - 'width': 1, - 'height': 1, - 'price': 0.01, - 'currency': 'TRY', - 'type': 'native', - 'mime_type': { - 'name': 'backfill', - 'force': false + { + 'id': 2, + 'creative_id': '3741', + 'width': 300, + 'height': 250, + 'price': 0.01, + 'currency': 'TRY', + 'type': 'video', + 'mime_type': { + 'name': 'backfill', + 'force': false + }, + 'bidder': 'admatic', + 'adomain': ['admatic.com.tr'], + 'party_tag': '', + 'iurl': 'https://www.admatic.com.tr' }, - 'bidder': 'admatic', - 'adomain': ['admatic.com.tr'], - 'party_tag': '{"native":{"ver":"1.1","assets":[{"id":1,"title":{"text":"title"}},{"id":4,"data":{"value":"body"}},{"id":5,"data":{"value":"sponsored"}},{"id":6,"data":{"value":"cta"}},{"id":2,"img":{"url":"https://www.admatic.com.tr","w":1200,"h":628}},{"id":3,"img":{"url":"https://www.admatic.com.tr","w":640,"h":480}}],"link":{"url":"https://www.admatic.com.tr"},"imptrackers":["https://www.admatic.com.tr"]}}', - 'iurl': 'https://www.admatic.com.tr' - } - ], - 'cur': 'TRY', - 'queryId': 'cdnbh24rlv0hhkpfpln0', - 'status': true - }}; + { + 'id': 3, + 'creative_id': '3742', + 'width': 1, + 'height': 1, + 'price': 0.01, + 'currency': 'TRY', + 'type': 'native', + 'mime_type': { + 'name': 'backfill', + 'force': false + }, + 'bidder': 'admatic', + 'adomain': ['admatic.com.tr'], + 'party_tag': '{"native":{"ver":"1.1","assets":[{"id":1,"title":{"text":"title"}},{"id":4,"data":{"value":"body"}},{"id":5,"data":{"value":"sponsored"}},{"id":6,"data":{"value":"cta"}},{"id":2,"img":{"url":"https://www.admatic.com.tr","w":1200,"h":628}},{"id":3,"img":{"url":"https://www.admatic.com.tr","w":640,"h":480}}],"link":{"url":"https://www.admatic.com.tr"},"imptrackers":["https://www.admatic.com.tr"]}}', + 'iurl': 'https://www.admatic.com.tr' + } + ], + 'cur': 'TRY', + 'queryId': 'cdnbh24rlv0hhkpfpln0', + 'status': true + } + }; const expectedResponse = [ { @@ -1136,7 +1138,7 @@ describe('admaticBidAdapter', () => { ] }; - const result = spec.interpretResponse(bids, {data: request}); + const result = spec.interpretResponse(bids, { data: request }); expect(result).to.eql(expectedResponse); }); @@ -1147,14 +1149,16 @@ describe('admaticBidAdapter', () => { 'type': 'admatic' } }; - const bids = { body: { - data: [], - 'queryId': 'cdnbh24rlv0hhkpfpln0', - 'status': true, - 'cur': 'TRY' - }}; + const bids = { + body: { + data: [], + 'queryId': 'cdnbh24rlv0hhkpfpln0', + 'status': true, + 'cur': 'TRY' + } + }; - const result = spec.interpretResponse(bids, {data: request}); + const result = spec.interpretResponse(bids, { data: request }); expect(result.length).to.equal(0); }); }); diff --git a/test/spec/modules/admediaBidAdapter_spec.js b/test/spec/modules/admediaBidAdapter_spec.js index 53ccade28e2..2774e604f8a 100644 --- a/test/spec/modules/admediaBidAdapter_spec.js +++ b/test/spec/modules/admediaBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/admediaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/admediaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; const ENDPOINT_URL = 'https://prebid.admedia.com/bidder/'; @@ -12,7 +12,7 @@ describe('admediaBidAdapter', function () { adUnitCode: 'adunit-code', bidder: 'admedia', bidId: 'g7ghhs78', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { placementId: '782332', aid: '86858', @@ -31,7 +31,7 @@ describe('admediaBidAdapter', function () { adUnitCode: 'adunit-code', bidder: 'admedia', bidId: 'g7ghhs78', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { placementId: '782332', aid: '86858' diff --git a/test/spec/modules/adminationBidAdapter_spec.js b/test/spec/modules/adminationBidAdapter_spec.js new file mode 100644 index 00000000000..b3401b3c0c4 --- /dev/null +++ b/test/spec/modules/adminationBidAdapter_spec.js @@ -0,0 +1,774 @@ +import { expect } from 'chai'; +import { + spec as adapter, + createDomain, + storage, +} from 'modules/adnimationBidAdapter'; +import * as utils from 'src/utils.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; +import { + hashCode, + extractPID, + extractCID, + extractSubDomain, + getStorageItem, + setStorageItem, + tryParseJSON, + getUniqueDealId, +} from '../../../libraries/vidazooUtils/bidderUtils.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; + +export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; + +const SUB_DOMAIN = 'exchange'; + +const BID = { + 'bidId': '2d52001cabd527', + 'adUnitCode': 'div-gpt-ad-12345-0', + 'params': { + 'subDomain': SUB_DOMAIN, + 'cId': '59db6b3b4ffaa70004f45cdc', + 'pId': '59ac17c192832d0011283fe3', + 'bidFloor': 0.1, + 'ext': { + 'param1': 'loremipsum', + 'param2': 'dolorsitamet' + } + }, + 'placementCode': 'div-gpt-ad-1460505748561-0', + 'transactionId': 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', + 'sizes': [[300, 250], [300, 600]], + 'bidderRequestId': '1fdb5ff1b6eaa7', + 'auctionId': 'auction_id', + 'bidRequestsCount': 4, + 'bidderRequestsCount': 3, + 'bidderWinsCount': 1, + 'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a', + 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', + 'mediaTypes': [BANNER], + 'ortb2Imp': { + 'ext': { + 'gpid': '0123456789' + } + } +}; + +const VIDEO_BID = { + 'bidId': '2d52001cabd527', + 'adUnitCode': '63550ad1ff6642d368cba59dh5884270560', + 'bidderRequestId': '12a8ae9ada9c13', + 'transactionId': '56e184c6-bde9-497b-b9b9-cf47a61381ee', + 'auctionId': 'auction_id', + 'bidRequestsCount': 4, + 'bidderRequestsCount': 3, + 'bidderWinsCount': 1, + 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', + 'params': { + 'subDomain': SUB_DOMAIN, + 'cId': '635509f7ff6642d368cb9837', + 'pId': '59ac17c192832d0011283fe3', + 'bidFloor': 0.1 + }, + 'sizes': [[545, 307]], + 'mediaTypes': { + 'video': { + 'playerSize': [[545, 307]], + 'context': 'instream', + 'mimes': [ + 'video/mp4', + 'application/javascript' + ], + 'protocols': [2, 3, 5, 6], + 'maxduration': 60, + 'minduration': 0, + 'startdelay': 0, + 'linearity': 1, + 'api': [2], + 'placement': 1 + } + } +} + +const ORTB2_DEVICE = { + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + w: 980, + h: 1720, + dnt: 0, + ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/125.0.6422.80 Mobile/15E148 Safari/604.1', + language: 'en', + devicetype: 1, + make: 'Apple', + model: 'iPhone 12 Pro Max', + os: 'iOS', + osv: '17.4', + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, +}; + +const BIDDER_REQUEST = { + 'gdprConsent': { + 'consentString': 'consent_string', + 'gdprApplies': true + }, + 'gppString': 'gpp_string', + 'gppSid': [7], + 'uspConsent': 'consent_string', + 'refererInfo': { + 'page': 'https://www.greatsite.com', + 'ref': 'https://www.somereferrer.com' + }, + 'ortb2': { + 'site': { + 'content': { + 'language': 'en' + } + }, + 'regs': { + 'gpp': 'gpp_string', + 'gpp_sid': [7], + 'coppa': 0 + }, + 'device': ORTB2_DEVICE, + } +}; + +const SERVER_RESPONSE = { + body: { + cid: 'testcid123', + results: [{ + 'ad': '', + 'price': 0.8, + 'creativeId': '12610997325162499419', + 'exp': 30, + 'width': 300, + 'height': 250, + 'advertiserDomains': ['securepubads.g.doubleclick.net'], + 'cookies': [{ + 'src': 'https://sync.com', + 'type': 'iframe' + }, { + 'src': 'https://sync.com', + 'type': 'img' + }] + }] + } +}; + +const VIDEO_SERVER_RESPONSE = { + body: { + 'cid': '635509f7ff6642d368cb9837', + 'results': [{ + 'ad': '', + 'advertiserDomains': ['adnimation.com'], + 'exp': 60, + 'width': 545, + 'height': 307, + 'mediaType': 'video', + 'creativeId': '12610997325162499419', + 'price': 2, + 'cookies': [] + }] + } +}; + +const ORTB2_OBJ = { + "device": ORTB2_DEVICE, + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } +}; + +const REQUEST = { + data: { + width: 300, + height: 250, + bidId: '2d52001cabd527' + } +}; + +function getTopWindowQueryParams() { + try { + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); + return parsedUrl.search; + } catch (e) { + return ''; + } +} + +describe('adnimationBidAdapter', function () { + before(() => config.resetConfig()); + after(() => config.resetConfig()); + + describe('validate spec', function () { + it('exists and is a function', function () { + expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.buildRequests).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.interpretResponse).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.getUserSyncs).to.exist.and.to.be.a('function'); + }); + + it('exists and is a string', function () { + expect(adapter.code).to.exist.and.to.be.a('string'); + }); + + it('exists and contains media types', function () { + expect(adapter.supportedMediaTypes).to.exist.and.to.be.an('array').with.length(2); + expect(adapter.supportedMediaTypes).to.contain.members([BANNER, VIDEO]); + }); + }); + + describe('validate bid requests', function () { + it('should require cId', function () { + const isValid = adapter.isBidRequestValid({ + params: { + pId: 'pid' + } + }); + expect(isValid).to.be.false; + }); + + it('should require pId', function () { + const isValid = adapter.isBidRequestValid({ + params: { + cId: 'cid' + } + }); + expect(isValid).to.be.false; + }); + + it('should validate correctly', function () { + const isValid = adapter.isBidRequestValid({ + params: { + cId: 'cid', + pId: 'pid' + } + }); + expect(isValid).to.be.true; + }); + }); + + describe('build requests', function () { + let sandbox; + before(function () { + getGlobal().bidderSettings = { + adnimation: { + storageAllowed: true + } + }; + sandbox = sinon.createSandbox(); + sandbox.stub(Date, 'now').returns(1000); + }); + + it('should build video request', function () { + const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); + config.setConfig({ + bidderTimeout: 3000 + }); + const requests = adapter.buildRequests([VIDEO_BID], BIDDER_REQUEST); + expect(requests).to.have.length(1); + expect(requests[0]).to.deep.equal({ + method: 'POST', + url: `${createDomain(SUB_DOMAIN)}/prebid/multi/635509f7ff6642d368cb9837`, + data: { + adUnitCode: '63550ad1ff6642d368cba59dh5884270560', + bidFloor: 0.1, + bidId: '2d52001cabd527', + bidderVersion: adapter.version, + bidderRequestId: '12a8ae9ada9c13', + cb: 1000, + gdpr: 1, + gdprConsent: 'consent_string', + usPrivacy: 'consent_string', + gppString: 'gpp_string', + gppSid: [7], + prebidVersion: version, + transactionId: '56e184c6-bde9-497b-b9b9-cf47a61381ee', + auctionId: 'auction_id', + bidRequestsCount: 4, + bidderRequestsCount: 3, + bidderWinsCount: 1, + bidderTimeout: 3000, + publisherId: '59ac17c192832d0011283fe3', + url: 'https%3A%2F%2Fwww.greatsite.com', + referrer: 'https://www.somereferrer.com', + res: `${window.top.screen.width}x${window.top.screen.height}`, + schain: VIDEO_BID.schain, + sizes: ['545x307'], + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + device: ORTB2_DEVICE, + uniqueDealId: `${hashUrl}_${Date.now().toString()}`, + uqs: getTopWindowQueryParams(), + mediaTypes: { + video: { + api: [2], + context: 'instream', + linearity: 1, + maxduration: 60, + mimes: [ + 'video/mp4', + 'application/javascript' + ], + minduration: 0, + placement: 1, + playerSize: [[545, 307]], + protocols: [2, 3, 5, 6], + startdelay: 0 + } + }, + gpid: '', + cat: [], + contentLang: 'en', + contentData: [], + isStorageAllowed: true, + pagecat: [], + ortb2: ORTB2_OBJ, + userData: [], + coppa: 0 + } + }); + }); + + it('should build banner request for each size', function () { + const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); + config.setConfig({ + bidderTimeout: 3000 + }); + const requests = adapter.buildRequests([BID], BIDDER_REQUEST); + expect(requests).to.have.length(1); + expect(requests[0]).to.deep.equal({ + method: 'POST', + url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`, + data: { + gdprConsent: 'consent_string', + gdpr: 1, + gppString: 'gpp_string', + gppSid: [7], + usPrivacy: 'consent_string', + transactionId: 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', + auctionId: 'auction_id', + bidRequestsCount: 4, + bidderRequestsCount: 3, + bidderWinsCount: 1, + bidderTimeout: 3000, + bidderRequestId: '1fdb5ff1b6eaa7', + sizes: ['300x250', '300x600'], + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + device: ORTB2_DEVICE, + url: 'https%3A%2F%2Fwww.greatsite.com', + referrer: 'https://www.somereferrer.com', + cb: 1000, + bidFloor: 0.1, + bidId: '2d52001cabd527', + adUnitCode: 'div-gpt-ad-12345-0', + publisherId: '59ac17c192832d0011283fe3', + uniqueDealId: `${hashUrl}_${Date.now().toString()}`, + bidderVersion: adapter.version, + prebidVersion: version, + schain: BID.schain, + res: `${window.top.screen.width}x${window.top.screen.height}`, + mediaTypes: [BANNER], + gpid: '0123456789', + uqs: getTopWindowQueryParams(), + 'ext.param1': 'loremipsum', + 'ext.param2': 'dolorsitamet', + cat: [], + contentLang: 'en', + contentData: [], + isStorageAllowed: true, + pagecat: [], + ortb2Imp: BID.ortb2Imp, + ortb2: ORTB2_OBJ, + userData: [], + coppa: 0 + } + }); + }); + + after(function () { + getGlobal().bidderSettings = {}; + sandbox.restore(); + }); + }); + describe('getUserSyncs', function () { + it('should have valid user sync with iframeEnabled', function () { + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.adnimation.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' + }]); + }); + + it('should have valid user sync with cid on response', function () { + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.adnimation.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' + }]); + }); + + it('should have valid user sync with pixelEnabled', function () { + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + 'url': 'https://sync.adnimation.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', + 'type': 'image' + }]); + }); + + it('should have valid user sync with coppa on response', function () { + config.setConfig({ + coppa: 1 + }); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.adnimation.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' + }]); + }); + + it('should generate url with consent data', function () { + const gdprConsent = { + gdprApplies: true, + consentString: 'consent_string' + }; + const uspConsent = 'usp_string'; + const gppConsent = { + gppString: 'gpp_string', + applicableSections: [7] + } + + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + + expect(result).to.deep.equal([{ + 'url': 'https://sync.adnimation.com/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', + 'type': 'image' + }]); + }); + }); + + describe('interpret response', function () { + it('should return empty array when there is no response', function () { + const responses = adapter.interpretResponse(null); + expect(responses).to.be.empty; + }); + + it('should return empty array when there is no ad', function () { + const responses = adapter.interpretResponse({ price: 1, ad: '' }); + expect(responses).to.be.empty; + }); + + it('should return empty array when there is no price', function () { + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); + expect(responses).to.be.empty; + }); + + it('should return an array of interpreted banner responses', function () { + const responses = adapter.interpretResponse(SERVER_RESPONSE, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0]).to.deep.equal({ + requestId: '2d52001cabd527', + cpm: 0.8, + width: 300, + height: 250, + creativeId: '12610997325162499419', + currency: 'USD', + netRevenue: true, + ttl: 30, + ad: '', + meta: { + advertiserDomains: ['securepubads.g.doubleclick.net'] + } + }); + }); + + it('should get meta from response metaData', function () { + const serverResponse = utils.deepClone(SERVER_RESPONSE); + serverResponse.body.results[0].metaData = { + advertiserDomains: ['adnimation.com'], + agencyName: 'Agency Name', + }; + const responses = adapter.interpretResponse(serverResponse, REQUEST); + expect(responses[0].meta).to.deep.equal({ + advertiserDomains: ['adnimation.com'], + agencyName: 'Agency Name' + }); + }); + + it('should return an array of interpreted video responses', function () { + const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0]).to.deep.equal({ + requestId: '2d52001cabd527', + cpm: 2, + width: 545, + height: 307, + mediaType: 'video', + creativeId: '12610997325162499419', + currency: 'USD', + netRevenue: true, + ttl: 60, + vastXml: '', + meta: { + advertiserDomains: ['adnimation.com'] + } + }); + }); + + it('should take default TTL', function () { + const serverResponse = utils.deepClone(SERVER_RESPONSE); + delete serverResponse.body.results[0].exp; + const responses = adapter.interpretResponse(serverResponse, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0].ttl).to.equal(300); + }); + }); + + describe('user id system', function () { + TEST_ID_SYSTEMS.forEach((idSystemProvider) => { + const id = Date.now().toString(); + const bid = utils.deepClone(BID); + + const userId = (function () { + switch (idSystemProvider) { + case 'lipb': + return { lipbid: id }; + case 'id5id': + return { uid: id }; + default: + return id; + } + })(); + + bid.userId = { + [idSystemProvider]: userId + }; + + it(`should include 'uid.${idSystemProvider}' in request params`, function () { + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id); + }); + }); + // testing bid.userIdAsEids handling + it("should include user ids from bid.userIdAsEids (length=1)", function() { + const bid = utils.deepClone(BID); + bid.userIdAsEids = [ + { + "source": "audigent.com", + "uids": [{ "id": "fakeidi6j6dlc6e" }] + } + ] + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e"); + }) + it("should include user ids from bid.userIdAsEids (length=2)", function() { + const bid = utils.deepClone(BID); + bid.userIdAsEids = [ + { + "source": "audigent.com", + "uids": [{ "id": "fakeidi6j6dlc6e" }] + }, + { + "source": "rwdcntrl.net", + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] + } + ] + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e"); + expect(requests[0].data['uid.rwdcntrl.net']).to.equal("fakeid6f35197d5c"); + }) + // testing user.ext.eid handling + it("should include user ids from user.ext.eid (length=1)", function() { + const bid = utils.deepClone(BID); + bid.user = { + ext: { + eids: [ + { + "source": "pubcid.org", + "uids": [{ "id": "fakeid8888dlc6e" }] + } + ] + } + } + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e"); + }) + it("should include user ids from user.ext.eid (length=2)", function() { + const bid = utils.deepClone(BID); + bid.user = { + ext: { + eids: [ + { + "source": "pubcid.org", + "uids": [{ "id": "fakeid8888dlc6e" }] + }, + { + "source": "adserver.org", + "uids": [{ "id": "fakeid495ff1" }] + } + ] + } + } + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e"); + expect(requests[0].data['uid.adserver.org']).to.equal("fakeid495ff1"); + }) + }); + + describe('alternate param names extractors', function () { + it('should return undefined when param not supported', function () { + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); + expect(cid).to.be.undefined; + expect(pid).to.be.undefined; + expect(subDomain).to.be.undefined; + }); + + it('should return value when param supported', function () { + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); + expect(cid).to.be.equal('1'); + expect(pid).to.be.equal('2'); + expect(subDomain).to.be.equal('prebid'); + }); + }); + + describe('unique deal id', function () { + before(function () { + getGlobal().bidderSettings = { + adnimation: { + storageAllowed: true + } + }; + }); + after(function () { + getGlobal().bidderSettings = {}; + }); + const key = 'myKey'; + let uniqueDealId; + beforeEach(() => { + uniqueDealId = getUniqueDealId(storage, key, 0); + }) + + it('should get current unique deal id', function (done) { + // waiting some time so `now` will become past + setTimeout(() => { + const current = getUniqueDealId(storage, key); + expect(current).to.be.equal(uniqueDealId); + done(); + }, 200); + }); + + it('should get new unique deal id on expiration', function (done) { + setTimeout(() => { + const current = getUniqueDealId(storage, key, 100); + expect(current).to.not.be.equal(uniqueDealId); + done(); + }, 200) + }); + }); + + describe('storage utils', function () { + before(function () { + getGlobal().bidderSettings = { + adnimation: { + storageAllowed: true + } + }; + }); + after(function () { + getGlobal().bidderSettings = {}; + }); + it('should get value from storage with create param', function () { + const now = Date.now(); + const clock = useFakeTimers({ + shouldAdvanceTime: true, + now + }); + setStorageItem(storage, 'myKey', 2020); + const { value, created } = getStorageItem(storage, 'myKey'); + expect(created).to.be.equal(now); + expect(value).to.be.equal(2020); + expect(typeof value).to.be.equal('number'); + expect(typeof created).to.be.equal('number'); + clock.restore(); + }); + + it('should get external stored value', function () { + const value = 'superman' + window.localStorage.setItem('myExternalKey', value); + const item = getStorageItem(storage, 'myExternalKey'); + expect(item).to.be.equal(value); + }); + + it('should parse JSON value', function () { + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); + expect(event).to.be.equal('send'); + }); + + it('should get original value on parse fail', function () { + const value = 21; + const parsed = tryParseJSON(value); + expect(typeof parsed).to.be.equal('number'); + expect(parsed).to.be.equal(value); + }); + }); +}); diff --git a/test/spec/modules/admixerBidAdapter_spec.js b/test/spec/modules/admixerBidAdapter_spec.js index db8dbd0d203..644ce176867 100644 --- a/test/spec/modules/admixerBidAdapter_spec.js +++ b/test/spec/modules/admixerBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/admixerBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from '../../../src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/admixerBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from '../../../src/config.js'; const BIDDER_CODE = 'admixer'; const RTB_BIDDER_CODE = 'rtbstack' @@ -309,9 +309,9 @@ describe('AdmixerAdapter', function () { ]; it('Returns valid values', function () { - const userSyncAll = spec.getUserSyncs({pixelEnabled: true, iframeEnabled: true}, responses); - const userSyncImg = spec.getUserSyncs({pixelEnabled: true, iframeEnabled: false}, responses); - const userSyncFrm = spec.getUserSyncs({pixelEnabled: false, iframeEnabled: true}, responses); + const userSyncAll = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, responses); + const userSyncImg = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: false }, responses); + const userSyncFrm = spec.getUserSyncs({ pixelEnabled: false, iframeEnabled: true }, responses); expect(userSyncAll).to.be.an('array').with.lengthOf(2); expect(userSyncImg).to.be.an('array').with.lengthOf(1); expect(userSyncImg[0].url).to.be.equal(imgUrl); diff --git a/test/spec/modules/admixerIdSystem_spec.js b/test/spec/modules/admixerIdSystem_spec.js index af3783558f9..9c251a46e43 100644 --- a/test/spec/modules/admixerIdSystem_spec.js +++ b/test/spec/modules/admixerIdSystem_spec.js @@ -1,9 +1,9 @@ -import {admixerIdSubmodule} from 'modules/admixerIdSystem.js'; +import { admixerIdSubmodule } from 'modules/admixerIdSystem.js'; import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; const pid = '4D393FAC-B6BB-4E19-8396-0A4813607316'; -const getIdParams = {params: {pid: pid}}; +const getIdParams = { params: { pid: pid } }; describe('admixerId tests', function () { let logErrorStub; @@ -22,15 +22,15 @@ describe('admixerId tests', function () { admixerIdSubmodule.getId({}); expect(logErrorStub.callCount).to.be.equal(2); - admixerIdSubmodule.getId({params: {}}); + admixerIdSubmodule.getId({ params: {} }); expect(logErrorStub.callCount).to.be.equal(3); - admixerIdSubmodule.getId({params: {pid: 123}}); + admixerIdSubmodule.getId({ params: { pid: 123 } }); expect(logErrorStub.callCount).to.be.equal(4); }); it('should NOT call the admixer id endpoint if gdpr applies but consent string is missing', function () { - const submoduleCallback = admixerIdSubmodule.getId(getIdParams, {gdpr: { gdprApplies: true }}); + const submoduleCallback = admixerIdSubmodule.getId(getIdParams, { gdpr: { gdprApplies: true } }); expect(submoduleCallback).to.be.undefined; }); @@ -57,7 +57,7 @@ describe('admixerId tests', function () { request.respond( 200, {}, - JSON.stringify({setData: {visitorid: '571058d70bce453b80e6d98b4f8a81e3'}}) + JSON.stringify({ setData: { visitorid: '571058d70bce453b80e6d98b4f8a81e3' } }) ); expect(callBackSpy.calledOnce).to.be.true; expect(callBackSpy.args[0][0]).to.be.eq('571058d70bce453b80e6d98b4f8a81e3'); diff --git a/test/spec/modules/adnowBidAdapter_spec.js b/test/spec/modules/adnowBidAdapter_spec.js index a8013e3fa04..1048a453411 100644 --- a/test/spec/modules/adnowBidAdapter_spec.js +++ b/test/spec/modules/adnowBidAdapter_spec.js @@ -151,8 +151,8 @@ describe('adnowBidAdapter', function () { const noBidResponses = [ false, {}, - {body: false}, - {body: {}} + { body: false }, + { body: {} } ]; noBidResponses.forEach(response => { diff --git a/test/spec/modules/adnuntiusBidAdapter_spec.js b/test/spec/modules/adnuntiusBidAdapter_spec.js index 6c6f08b8750..1e642092a30 100644 --- a/test/spec/modules/adnuntiusBidAdapter_spec.js +++ b/test/spec/modules/adnuntiusBidAdapter_spec.js @@ -1,15 +1,15 @@ import '../../../src/prebid.js'; -import {expect} from 'chai'; -import {spec} from 'modules/adnuntiusBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/adnuntiusBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; -import {deepClone, getUnixTimestampFromNow} from 'src/utils.js'; -import {getStorageManager} from 'src/storageManager.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; -import {getWinDimensions} from '../../../src/utils.js'; +import { deepClone, getUnixTimestampFromNow } from 'src/utils.js'; +import { getStorageManager } from 'src/storageManager.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; +import { getWinDimensions } from '../../../src/utils.js'; -import {getGlobalVarName} from '../../../src/buildOptions.js'; +import { getGlobalVarName } from '../../../src/buildOptions.js'; describe('adnuntiusBidAdapter', function () { const sandbox = sinon.createSandbox(); @@ -138,51 +138,55 @@ describe('adnuntiusBidAdapter', function () { } ]; - const legacyNativeBidderRequest = {bid: [ - { - bidId: 'adn-0000000000000551', - bidder: 'adnuntius', - params: { - auId: '0000000000000551', - network: 'adnuntius', - }, - mediaTypes: { - native: { - sizes: [[200, 200], [300, 300]], - image: { - required: true, - sizes: [250, 250] + const legacyNativeBidderRequest = { + bid: [ + { + bidId: 'adn-0000000000000551', + bidder: 'adnuntius', + params: { + auId: '0000000000000551', + network: 'adnuntius', + }, + mediaTypes: { + native: { + sizes: [[200, 200], [300, 300]], + image: { + required: true, + sizes: [250, 250] + } } } - } - }]}; + }] + }; - const nativeBidderRequest = {bid: [ - { - bidId: 'adn-0000000000000551', - bidder: 'adnuntius', - params: { - auId: '0000000000000551', - network: 'adnuntius', - }, - mediaTypes: { - native: { - sizes: [[200, 200], [300, 300]], - ortb: { - assets: [{ - id: 1, - required: 1, - img: { - type: 3, - w: 250, - h: 250, - } - }] + const nativeBidderRequest = { + bid: [ + { + bidId: 'adn-0000000000000551', + bidder: 'adnuntius', + params: { + auId: '0000000000000551', + network: 'adnuntius', + }, + mediaTypes: { + native: { + sizes: [[200, 200], [300, 300]], + ortb: { + assets: [{ + id: 1, + required: 1, + img: { + type: 3, + w: 250, + h: 250, + } + }] + } } - } - }, - } - ]}; + }, + } + ] + }; const multiBidAndFormatRequest = { bid: [{ @@ -970,7 +974,7 @@ describe('adnuntiusBidAdapter', function () { dealIdRequest[0].params.dealId = 'simplestringdeal'; dealIdRequest[0].params.inventory = { pmp: { - deals: [{id: '123', bidfloor: 12, bidfloorcur: 'USD'}] + deals: [{ id: '123', bidfloor: 12, bidfloorcur: 'USD' }] } }; let request = spec.buildRequests(dealIdRequest, {}); @@ -1146,11 +1150,11 @@ describe('adnuntiusBidAdapter', function () { expect(request.length).to.equal(1); expect(request[0]).to.have.property('url') const data = JSON.parse(request[0].data); - expect(countMatches(data.adUnits[0].kv, {'9090': ['take it over']})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'merge': ['this']})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'9090': 'should-be-retained'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'45678': 'true'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'12345': 'true'})).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': ['take it over'] })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { 'merge': ['this'] })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': 'should-be-retained' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '45678': 'true' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '12345': 'true' })).to.equal(1); expect(data.adUnits[0].kv.length).to.equal(5); delete bidderRequests[0].params.targeting; @@ -1178,21 +1182,21 @@ describe('adnuntiusBidAdapter', function () { }; bidderRequests[0].params.targeting = { kv: [ - {'merge': ['this']}, - {'9090': ['take it over']} + { 'merge': ['this'] }, + { '9090': ['take it over'] } ] }; const request = config.runWithBidder('adnuntius', () => spec.buildRequests(bidderRequests, { ortb2 })); expect(request.length).to.equal(1); expect(request[0]).to.have.property('url') const data = JSON.parse(request[0].data); - expect(countMatches(data.adUnits[0].kv, {'from': 'user'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'9090': 'from-user'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'9090': ['take it over']})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'merge': ['this']})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'9090': 'should-be-retained'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'45678': 'true'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'12345': 'true'})).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { 'from': 'user' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': 'from-user' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': ['take it over'] })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { 'merge': ['this'] })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': 'should-be-retained' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '45678': 'true' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '12345': 'true' })).to.equal(1); expect(data.adUnits[0].kv.length).to.equal(7); delete bidderRequests[0].params.targeting; @@ -1214,9 +1218,9 @@ describe('adnuntiusBidAdapter', function () { expect(request.length).to.equal(1); expect(request[0]).to.have.property('url') const data = JSON.parse(request[0].data); - expect(countMatches(data.adUnits[0].kv, {'9090': 'should-be-retained'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'45678': 'true'})).to.equal(1); - expect(countMatches(data.adUnits[0].kv, {'12345': 'true'})).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '9090': 'should-be-retained' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '45678': 'true' })).to.equal(1); + expect(countMatches(data.adUnits[0].kv, { '12345': 'true' })).to.equal(1); expect(data.adUnits[0].kv.length).to.equal(3); delete bidderRequests[0].params.targeting; @@ -1368,7 +1372,7 @@ describe('adnuntiusBidAdapter', function () { expect(request[0]).to.have.property('url'); expectUrlsEqual(request[0].url, `${ENDPOINT_URL_BASE}&userId=${usi}`); - const ortb2 = {user: {ext: {eids: [{source: 'a', uids: [{id: '123', atype: 1}]}, {source: 'b', uids: [{id: '456', atype: 3, ext: {some: '1'}}]}]}}}; + const ortb2 = { user: { ext: { eids: [{ source: 'a', uids: [{ id: '123', atype: 1 }] }, { source: 'b', uids: [{ id: '456', atype: 3, ext: { some: '1' } }] }] } } }; request = config.runWithBidder('adnuntius', () => spec.buildRequests(req, { bids: req, ortb2: ortb2 })); expect(request.length).to.equal(1); expect(request[0]).to.have.property('url'); @@ -1386,7 +1390,7 @@ describe('adnuntiusBidAdapter', function () { expect(request[0]).to.have.property('url'); expectUrlsEqual(request[0].url, `${ENDPOINT_URL_BASE}&userId=different_user_id`); - const eids = [{source: 'pubcid', uids: [{id: '123', atype: 1}]}, {source: 'otherid', uids: [{id: '456', atype: 3, ext: {some: '1'}}]}]; + const eids = [{ source: 'pubcid', uids: [{ id: '123', atype: 1 }] }, { source: 'otherid', uids: [{ id: '456', atype: 3, ext: { some: '1' } }] }]; req[0].params.userId = 'different_user_id'; req[0].params.userIdAsEids = eids; request = config.runWithBidder('adnuntius', () => spec.buildRequests(req, { bids: req })); diff --git a/test/spec/modules/adoceanBidAdapter_spec.js b/test/spec/modules/adoceanBidAdapter_spec.js index 53a82ec963d..fe0096bf91b 100644 --- a/test/spec/modules/adoceanBidAdapter_spec.js +++ b/test/spec/modules/adoceanBidAdapter_spec.js @@ -36,7 +36,7 @@ describe('AdoceanAdapter', function () { }); it('should return false when required params are not passed', function () { - const invalidBid = Object.assign({}, bannerBid, {params: {masterId: 0}}); + const invalidBid = Object.assign({}, bannerBid, { params: { masterId: 0 } }); expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); diff --git a/test/spec/modules/adpartnerBidAdapter_spec.js b/test/spec/modules/adpartnerBidAdapter_spec.js index fdc63bade6d..f13ef1fd782 100644 --- a/test/spec/modules/adpartnerBidAdapter_spec.js +++ b/test/spec/modules/adpartnerBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/adpartnerBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH } from 'modules/adpartnerBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as miUtils from 'libraries/mediaImpactUtils/index.js'; const BIDDER_CODE = 'adpartner'; @@ -144,9 +144,9 @@ describe('AdpartnerAdapter', function () { 'test.domain' ], 'syncs': [ - {'type': 'image', 'url': 'https://test.domain/tracker_1.gif'}, - {'type': 'image', 'url': 'https://test.domain/tracker_2.gif'}, - {'type': 'image', 'url': 'https://test.domain/tracker_3.gif'} + { 'type': 'image', 'url': 'https://test.domain/tracker_1.gif' }, + { 'type': 'image', 'url': 'https://test.domain/tracker_2.gif' }, + { 'type': 'image', 'url': 'https://test.domain/tracker_3.gif' } ], 'winNotification': [ { @@ -154,7 +154,7 @@ describe('AdpartnerAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 @@ -179,7 +179,7 @@ describe('AdpartnerAdapter', function () { expect(result[0].currency).to.equal('USD'); expect(result[0].ttl).to.equal(60); expect(result[0].meta.advertiserDomains).to.deep.equal(['test.domain']); - expect(result[0].winNotification[0]).to.deep.equal({'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': {'ad': [{'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'}], 'unit_id': 1234, 'site_id': 123}}); + expect(result[0].winNotification[0]).to.deep.equal({ 'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': { 'ad': [{ 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' }], 'unit_id': 1234, 'site_id': 123 } }); }); }); @@ -227,7 +227,7 @@ describe('AdpartnerAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 @@ -268,9 +268,9 @@ describe('AdpartnerAdapter', function () { 'test.domain' ], 'syncs': [ - {'type': 'image', 'link': 'https://test.domain/tracker_1.gif'}, - {'type': 'image', 'link': 'https://test.domain/tracker_2.gif'}, - {'type': 'image', 'link': 'https://test.domain/tracker_3.gif'} + { 'type': 'image', 'link': 'https://test.domain/tracker_1.gif' }, + { 'type': 'image', 'link': 'https://test.domain/tracker_2.gif' }, + { 'type': 'image', 'link': 'https://test.domain/tracker_3.gif' } ], 'winNotification': [ { @@ -278,7 +278,7 @@ describe('AdpartnerAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 diff --git a/test/spec/modules/adplusBidAdapter_spec.js b/test/spec/modules/adplusBidAdapter_spec.js index 5dc02ca37c5..2e60cf94357 100644 --- a/test/spec/modules/adplusBidAdapter_spec.js +++ b/test/spec/modules/adplusBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {ADPLUS_ENDPOINT, BIDDER_CODE, spec,} from 'modules/adplusBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { ADPLUS_ENDPOINT, BIDDER_CODE, spec, } from 'modules/adplusBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const TEST_UID = 'test-uid-value'; diff --git a/test/spec/modules/adplusIdSystem_spec.js b/test/spec/modules/adplusIdSystem_spec.js index 9a7d9458335..f13172dd729 100644 --- a/test/spec/modules/adplusIdSystem_spec.js +++ b/test/spec/modules/adplusIdSystem_spec.js @@ -4,7 +4,7 @@ import { ADPLUS_COOKIE_NAME, } from 'modules/adplusIdSystem.js'; import { server } from 'test/mocks/xhr.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; const UID_VALUE = '191223.3413767593'; diff --git a/test/spec/modules/adpod_spec.js b/test/spec/modules/adpod_spec.js index 6e94d98b488..e833666ef62 100644 --- a/test/spec/modules/adpod_spec.js +++ b/test/spec/modules/adpod_spec.js @@ -34,7 +34,7 @@ describe('adpod.js', function () { const fakeStoreFn = function(bids, callback) { const payload = []; - bids.forEach(bid => payload.push({uuid: bid.customCacheKey})); + bids.forEach(bid => payload.push({ uuid: bid.customCacheKey })); callback(null, payload); }; @@ -502,7 +502,7 @@ describe('adpod.js', function () { it('should not add bid to auction when Prebid Cache detects an existing key', function () { storeStub.callsFake(function(bids, callback) { const payload = []; - bids.forEach(bid => payload.push({uuid: bid.customCacheKey})); + bids.forEach(bid => payload.push({ uuid: bid.customCacheKey })); // fake a duplicate bid response from PBC (sets an empty string for the uuid) payload[1].uuid = ''; diff --git a/test/spec/modules/adponeBidAdapter_spec.js b/test/spec/modules/adponeBidAdapter_spec.js index f28eecdd6a8..ac8cd4a2fca 100644 --- a/test/spec/modules/adponeBidAdapter_spec.js +++ b/test/spec/modules/adponeBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/adponeBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; const EMPTY_ARRAY = []; @@ -66,7 +66,7 @@ describe('adponeBidAdapter', function () { it('should return false when necessary information is not found', function () { // empty bid - expect(spec.isBidRequestValid({bidId: '', params: {}})).to.be.false; + expect(spec.isBidRequestValid({ bidId: '', params: {} })).to.be.false; // empty bidId bid.bidId = ''; @@ -112,7 +112,7 @@ describe('adponeBidAdapter', function () { }); describe('interpretResponse', function () { let serverResponse; - const bidRequest = { data: {id: '1234'} }; + const bidRequest = { data: { id: '1234' } }; beforeEach(function () { serverResponse = { diff --git a/test/spec/modules/adprimeBidAdapter_spec.js b/test/spec/modules/adprimeBidAdapter_spec.js index a917d85d6ab..d49281d79c6 100644 --- a/test/spec/modules/adprimeBidAdapter_spec.js +++ b/test/spec/modules/adprimeBidAdapter_spec.js @@ -436,7 +436,7 @@ describe('AdprimeBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -445,9 +445,7 @@ describe('AdprimeBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.adprime.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -456,7 +454,7 @@ describe('AdprimeBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.adprime.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/adqueryBidAdapter_spec.js b/test/spec/modules/adqueryBidAdapter_spec.js index e101eaabdb2..b914bf0f5f8 100644 --- a/test/spec/modules/adqueryBidAdapter_spec.js +++ b/test/spec/modules/adqueryBidAdapter_spec.js @@ -45,7 +45,7 @@ describe('adqueryBidAdapter', function () { 'adDomains': ['https://example.com'], 'tag': ' ', 'adqLib': 'https://example.com/js/example.js', - 'mediaType': {'width': 300, 'height': 250, 'name': 'banner', 'type': 'banner300x250'}, + 'mediaType': { 'width': 300, 'height': 250, 'name': 'banner', 'type': 'banner300x250' }, 'cpm': 2.5, 'meta': { 'advertiserDomains': ['example.com'], @@ -431,7 +431,7 @@ describe('adqueryBidAdapter', function () { }) describe('buildRequests', function () { - const req = spec.buildRequests([ bidRequest ], { refererInfo: { } })[0] + const req = spec.buildRequests([bidRequest], { refererInfo: { } })[0] it('should return request object', function () { expect(req).to.not.be.null @@ -665,7 +665,7 @@ describe('adqueryBidAdapter', function () { } } } - ], {refererInfo: {}})[0] + ], { refererInfo: {} })[0] it('should include video', function () { expect(req_video.data.bidPageUrl).not.be.null @@ -734,7 +734,7 @@ describe('adqueryBidAdapter', function () { const req_video_for_floor = spec.buildRequests([ { "getFloor": function () { - return {currency: "USD", floor: 1.13}; + return { currency: "USD", floor: 1.13 }; }, "bidder": "adquery", "params": { @@ -921,7 +921,7 @@ describe('adqueryBidAdapter', function () { } } } - ], {refererInfo: {}})[0] + ], { refererInfo: {} })[0] it('data with floor must have video bidfloor property', function () { expect(req_video_for_floor.data.imp[0].video.bidfloor).eq(1.13); @@ -1078,7 +1078,7 @@ describe('adqueryBidAdapter', function () { expect(utils.triggerPixel.called).to.equal(true); }); it('should use nurl if exists', function () { - var response = spec.onBidWon({nurl: "https://example.com/test-nurl"}); + var response = spec.onBidWon({ nurl: "https://example.com/test-nurl" }); expect(response).to.be.an('undefined') expect(utils.triggerPixel.calledWith("https://example.com/test-nurl")).to.equal(true); }); diff --git a/test/spec/modules/adqueryIdSystem_spec.js b/test/spec/modules/adqueryIdSystem_spec.js index 9b7304d1984..ee02148162f 100644 --- a/test/spec/modules/adqueryIdSystem_spec.js +++ b/test/spec/modules/adqueryIdSystem_spec.js @@ -1,9 +1,9 @@ -import {adqueryIdSubmodule, storage} from 'modules/adqueryIdSystem.js'; -import {server} from 'test/mocks/xhr.js'; +import { adqueryIdSubmodule, storage } from 'modules/adqueryIdSystem.js'; +import { server } from 'test/mocks/xhr.js'; import sinon from 'sinon'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; const config = { storage: { diff --git a/test/spec/modules/adrelevantisBidAdapter_spec.js b/test/spec/modules/adrelevantisBidAdapter_spec.js index eb7d81dbd5f..2c46e0ddff0 100644 --- a/test/spec/modules/adrelevantisBidAdapter_spec.js +++ b/test/spec/modules/adrelevantisBidAdapter_spec.js @@ -73,7 +73,7 @@ describe('AdrelevantisAdapter', function () { const payload = JSON.parse(request.data); expect(payload.tags[0].private_sizes).to.exist; - expect(payload.tags[0].private_sizes).to.deep.equal([{width: 300, height: 250}]); + expect(payload.tags[0].private_sizes).to.deep.equal([{ width: 300, height: 250 }]); }); it('should add source and verison to the tag', function () { @@ -102,7 +102,7 @@ describe('AdrelevantisAdapter', function () { it('should populate the ad_types array on outstream requests', function () { const bidRequest = Object.assign({}, bidRequests[0]); bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; + bidRequest.mediaTypes.video = { context: 'outstream' }; const request = spec.buildRequests([bidRequest], {}); const payload = JSON.parse(request.data); @@ -226,12 +226,12 @@ describe('AdrelevantisAdapter', function () { site: { keywords: 'US Open', ext: { - data: {category: 'sports/tennis'} + data: { category: 'sports/tennis' } } } }; - const request = spec.buildRequests([bidRequest], {ortb2}); + const request = spec.buildRequests([bidRequest], { ortb2 }); const payload = JSON.parse(request.data); expect(payload.fpd.keywords).to.equal('US Open'); @@ -244,22 +244,22 @@ describe('AdrelevantisAdapter', function () { { mediaType: 'native', nativeParams: { - title: {required: true}, - body: {required: true}, - body2: {required: true}, - image: {required: true, sizes: [100, 100]}, - icon: {required: true}, - cta: {required: false}, - rating: {required: true}, - sponsoredBy: {required: true}, - privacyLink: {required: true}, - displayUrl: {required: true}, - address: {required: true}, - downloads: {required: true}, - likes: {required: true}, - phone: {required: true}, - price: {required: true}, - salePrice: {required: true} + title: { required: true }, + body: { required: true }, + body2: { required: true }, + image: { required: true, sizes: [100, 100] }, + icon: { required: true }, + cta: { required: false }, + rating: { required: true }, + sponsoredBy: { required: true }, + privacyLink: { required: true }, + displayUrl: { required: true }, + address: { required: true }, + downloads: { required: true }, + likes: { required: true }, + phone: { required: true }, + price: { required: true }, + salePrice: { required: true } } } ); @@ -268,22 +268,22 @@ describe('AdrelevantisAdapter', function () { const payload = JSON.parse(request.data); expect(payload.tags[0].native.layouts[0]).to.deep.equal({ - title: {required: true}, - description: {required: true}, - desc2: {required: true}, - main_image: {required: true, sizes: [{ width: 100, height: 100 }]}, - icon: {required: true}, - ctatext: {required: false}, - rating: {required: true}, - sponsored_by: {required: true}, - privacy_link: {required: true}, - displayurl: {required: true}, - address: {required: true}, - downloads: {required: true}, - likes: {required: true}, - phone: {required: true}, - price: {required: true}, - saleprice: {required: true}, + title: { required: true }, + description: { required: true }, + desc2: { required: true }, + main_image: { required: true, sizes: [{ width: 100, height: 100 }] }, + icon: { required: true }, + ctatext: { required: false }, + rating: { required: true }, + sponsored_by: { required: true }, + privacy_link: { required: true }, + displayurl: { required: true }, + address: { required: true }, + downloads: { required: true }, + likes: { required: true }, + phone: { required: true }, + price: { required: true }, + saleprice: { required: true }, privacy_supported: true }); expect(payload.tags[0].hb_source).to.equal(1); @@ -303,14 +303,14 @@ describe('AdrelevantisAdapter', function () { let request = spec.buildRequests([bidRequest], {}); let payload = JSON.parse(request.data); - expect(payload.tags[0].sizes).to.deep.equal([{width: 150, height: 100}, {width: 300, height: 250}]); + expect(payload.tags[0].sizes).to.deep.equal([{ width: 150, height: 100 }, { width: 300, height: 250 }]); delete bidRequest.sizes; request = spec.buildRequests([bidRequest], {}); payload = JSON.parse(request.data); - expect(payload.tags[0].sizes).to.deep.equal([{width: 1, height: 1}]); + expect(payload.tags[0].sizes).to.deep.equal([{ width: 1, height: 1 }]); }); it('should convert keyword params to proper form and attaches to request', function () { @@ -327,7 +327,7 @@ describe('AdrelevantisAdapter', function () { singleValNum: 123, emptyStr: '', emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped + badValue: { 'foo': 'bar' } // should be dropped } } } @@ -556,7 +556,7 @@ describe('AdrelevantisAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); @@ -572,7 +572,7 @@ describe('AdrelevantisAdapter', function () { }; let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); @@ -605,7 +605,7 @@ describe('AdrelevantisAdapter', function () { }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).to.have.property('vastXml'); expect(result[0]).to.have.property('vastImpUrl'); expect(result[0]).to.have.property('mediaType', 'video'); @@ -640,7 +640,7 @@ describe('AdrelevantisAdapter', function () { }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).to.have.property('vastUrl'); expect(result[0]).to.have.property('vastImpUrl'); expect(result[0]).to.have.property('mediaType', 'video'); @@ -689,7 +689,7 @@ describe('AdrelevantisAdapter', function () { }] } - const result = spec.interpretResponse({ body: response1 }, {bidderRequest}); + const result = spec.interpretResponse({ body: response1 }, { bidderRequest }); expect(result[0].native.title).to.equal('Native Creative'); expect(result[0].native.body).to.equal('Cool description great stuff'); expect(result[0].native.cta).to.equal('Do it'); @@ -717,7 +717,7 @@ describe('AdrelevantisAdapter', function () { }] }; - const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest}); + const result = spec.interpretResponse({ body: outstreamResponse }, { bidderRequest }); expect(result[0].renderer.config).to.deep.equal( bidderRequest.bids[0].renderer.options ); @@ -734,7 +734,7 @@ describe('AdrelevantisAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseWithDeal }, { bidderRequest }); expect(Object.keys(result[0].adrelevantis)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']); }); @@ -748,7 +748,7 @@ describe('AdrelevantisAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseAdvertiserId }, { bidderRequest }); expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']); }) }); diff --git a/test/spec/modules/adrinoBidAdapter_spec.js b/test/spec/modules/adrinoBidAdapter_spec.js index f86fe7126de..b97c0820ea1 100644 --- a/test/spec/modules/adrinoBidAdapter_spec.js +++ b/test/spec/modules/adrinoBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/adrinoBidAdapter.js'; -import {config} from '../../../src/config.js'; +import { config } from '../../../src/config.js'; import * as utils from '../../../src/utils.js'; describe('adrinoBidAdapter', function () { @@ -67,8 +67,8 @@ describe('adrinoBidAdapter', function () { }, sizes: [[300, 250], [970, 250]], userIdAsEids: [ - {source: 'src1.org', uids: [{id: '1234', atype: 1}]}, - {source: 'src2.org', uids: [{id: '5678', atype: 1}]} + { source: 'src1.org', uids: [{ id: '1234', atype: 1 }] }, + { source: 'src2.org', uids: [{ id: '5678', atype: 1 }] } ], adUnitCode: 'adunit-code-2', bidId: '12345678901234', @@ -78,7 +78,7 @@ describe('adrinoBidAdapter', function () { it('should build the request correctly', function () { const result = spec.buildRequests( - [ bidRequest ], + [bidRequest], { refererInfo: { page: 'http://example.com/' } } ); expect(result.length).to.equal(1); @@ -95,11 +95,11 @@ describe('adrinoBidAdapter', function () { expect(result[0].data[0].eids).to.be.an('array').with.lengthOf(2); expect(result[0].data[0].eids).to.deep.include({ source: 'src1.org', - uids: [{id: '1234', atype: 1}] + uids: [{ id: '1234', atype: 1 }] }); expect(result[0].data[0].eids).to.deep.include({ source: 'src2.org', - uids: [{id: '5678', atype: 1}] + uids: [{ id: '5678', atype: 1 }] }); }); }); @@ -131,8 +131,8 @@ describe('adrinoBidAdapter', function () { } }, userIdAsEids: [ - {source: 'src1.org', uids: [{id: '1234', atype: 1}]}, - {source: 'src2.org', uids: [{id: '5678', atype: 1}]} + { source: 'src1.org', uids: [{ id: '1234', atype: 1 }] }, + { source: 'src2.org', uids: [{ id: '5678', atype: 1 }] } ], adUnitCode: 'adunit-code', bidId: '12345678901234', @@ -141,9 +141,9 @@ describe('adrinoBidAdapter', function () { }; it('should build the request correctly with custom domain', function () { - config.setConfig({adrino: { host: 'https://stg-prebid-bidder.adrino.io' }}); + config.setConfig({ adrino: { host: 'https://stg-prebid-bidder.adrino.io' } }); const result = spec.buildRequests( - [ bidRequest ], + [bidRequest], { refererInfo: { page: 'http://example.com/' } } ); expect(result.length).to.equal(1); @@ -160,17 +160,17 @@ describe('adrinoBidAdapter', function () { expect(result[0].data[0].eids).to.be.an('array').with.lengthOf(2); expect(result[0].data[0].eids).to.deep.include({ source: 'src1.org', - uids: [{id: '1234', atype: 1}] + uids: [{ id: '1234', atype: 1 }] }); expect(result[0].data[0].eids).to.deep.include({ source: 'src2.org', - uids: [{id: '5678', atype: 1}] + uids: [{ id: '5678', atype: 1 }] }); }); it('should build the request correctly with gdpr', function () { const result = spec.buildRequests( - [ bidRequest ], + [bidRequest], { gdprConsent: { gdprApplies: true, consentString: 'abc123' }, refererInfo: { page: 'http://example.com/' } } ); expect(result.length).to.equal(1); @@ -187,17 +187,17 @@ describe('adrinoBidAdapter', function () { expect(result[0].data[0].eids).to.be.an('array').with.lengthOf(2); expect(result[0].data[0].eids).to.deep.include({ source: 'src1.org', - uids: [{id: '1234', atype: 1}] + uids: [{ id: '1234', atype: 1 }] }); expect(result[0].data[0].eids).to.deep.include({ source: 'src2.org', - uids: [{id: '5678', atype: 1}] + uids: [{ id: '5678', atype: 1 }] }); }); it('should build the request correctly without gdpr', function () { const result = spec.buildRequests( - [ bidRequest ], + [bidRequest], { refererInfo: { page: 'http://example.com/' } } ); expect(result.length).to.equal(1); @@ -214,11 +214,11 @@ describe('adrinoBidAdapter', function () { expect(result[0].data[0].eids).to.be.an('array').with.lengthOf(2); expect(result[0].data[0].eids).to.deep.include({ source: 'src1.org', - uids: [{id: '1234', atype: 1}] + uids: [{ id: '1234', atype: 1 }] }); expect(result[0].data[0].eids).to.deep.include({ source: 'src2.org', - uids: [{id: '5678', atype: 1}] + uids: [{ id: '5678', atype: 1 }] }); }); }); diff --git a/test/spec/modules/adriverBidAdapter_spec.js b/test/spec/modules/adriverBidAdapter_spec.js index 75c786c07eb..15608a74d33 100644 --- a/test/spec/modules/adriverBidAdapter_spec.js +++ b/test/spec/modules/adriverBidAdapter_spec.js @@ -377,7 +377,7 @@ describe('adriverAdapter', function () { adUnitCode: 'code' }] }; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); @@ -393,7 +393,7 @@ describe('adriverAdapter', function () { }; let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); }); @@ -517,7 +517,7 @@ describe('adriverAdapter', function () { const bitRequestGetFloorBySized = JSON.parse(JSON.stringify(bidRequests)); - bitRequestGetFloorBySized[0].getFloor = (requestParams = {currency: 'USD', mediaType: '*', size: '*'}) => { + bitRequestGetFloorBySized[0].getFloor = (requestParams = { currency: 'USD', mediaType: '*', size: '*' }) => { if (requestParams.size.length === 2 && requestParams.size[0] === 300 && requestParams.size[1] === 250) { return { 'currency': 'RUB', diff --git a/test/spec/modules/ads_interactiveBidAdapter_spec.js b/test/spec/modules/ads_interactiveBidAdapter_spec.js index c16f5a5a7b5..c3d27008182 100644 --- a/test/spec/modules/ads_interactiveBidAdapter_spec.js +++ b/test/spec/modules/ads_interactiveBidAdapter_spec.js @@ -482,7 +482,7 @@ describe('AdsInteractiveBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -491,9 +491,7 @@ describe('AdsInteractiveBidAdapter', function () { expect(syncData[0].url).to.equal('https://cstb.adsinteractive.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -502,7 +500,7 @@ describe('AdsInteractiveBidAdapter', function () { expect(syncData[0].url).to.equal('https://cstb.adsinteractive.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/adstirBidAdapter_spec.js b/test/spec/modules/adstirBidAdapter_spec.js index d7f8efc3c88..2bfb46bc700 100644 --- a/test/spec/modules/adstirBidAdapter_spec.js +++ b/test/spec/modules/adstirBidAdapter_spec.js @@ -175,7 +175,7 @@ describe('AdstirAdapter', function () { }); it('ref.page, ref.tloc and ref.referrer correspond to refererInfo', function () { - const [ request ] = spec.buildRequests([validBidRequests[0]], { + const [request] = spec.buildRequests([validBidRequests[0]], { auctionId: 'b06c5141-fe8f-4cdf-9d7d-54415490a917', refererInfo: { page: null, @@ -279,7 +279,7 @@ describe('AdstirAdapter', function () { }; const serializedSchain = '1.0,1!exchange1.example,1234%21abcd,1,bid-request-1,publisher%2C%20Inc.,publisher.example!exchange2.example,abcd,1,bid-request-2,intermediary,intermediary.example'; - const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); + const [request] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); const d = JSON.parse(request.data); expect(d.schain).to.deep.equal(serializedSchain); }); @@ -305,7 +305,7 @@ describe('AdstirAdapter', function () { }; const serializedSchain = '1.0,1!exchange1.example,1234%21abcd,1,,,!,,,,,!exchange2.example,abcd,1,,,'; - const [ request ] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); + const [request] = spec.buildRequests([utils.mergeDeep(utils.deepClone(validBidRequests[0]), { ortb2: { source: { ext: { schain } } } })], bidderRequest); const d = JSON.parse(request.data); expect(d.schain).to.deep.equal(serializedSchain); }); diff --git a/test/spec/modules/adtrgtmeBidAdapter_spec.js b/test/spec/modules/adtrgtmeBidAdapter_spec.js index 702086c48a2..95c40d66bb1 100644 --- a/test/spec/modules/adtrgtmeBidAdapter_spec.js +++ b/test/spec/modules/adtrgtmeBidAdapter_spec.js @@ -9,7 +9,7 @@ const DEFAULT_BANNER_URL = 'https://cdn.adtarget.me/libs/banner/300x250.jpg'; const BIDDER_VERSION = '1.0.7'; const PREBIDJS_VERSION = '$prebid.version$'; -const createBidRequest = ({bidId, adUnitCode, bidOverride, zid, ortb2}) => { +const createBidRequest = ({ bidId, adUnitCode, bidOverride, zid, ortb2 }) => { const bR = { auctionId: 'f3c594t-3o0ch1b0rm-ayn93c3o0ch1b0rm', adUnitCode, @@ -55,7 +55,7 @@ const createBidderRequest = (arr, code = 'default-code', ortb2 = {}) => { }; }; -const createRequestMock = ({bidId, adUnitCode, type, zid, bidOverride, pubIdMode, ortb2}) => { +const createRequestMock = ({ bidId, adUnitCode, type, zid, bidOverride, pubIdMode, ortb2 }) => { const bR = createBidRequest({ bidId: bidId || '84ab500420319d', adUnitCode: adUnitCode || '/1220291391/banner', @@ -101,10 +101,10 @@ const createResponseMock = (type) => { }] } }; - const { validBR, bidderRequest } = createRequestMock({type}); + const { validBR, bidderRequest } = createRequestMock({ type }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; - return {sR, data, bidderRequest}; + return { sR, data, bidderRequest }; } describe('Adtrgtme Bid Adapter:', () => { @@ -163,8 +163,8 @@ describe('Adtrgtme Bid Adapter:', () => { expect(pixels.length).to.equal(2); expect(pixels).to.deep.equal( [ - {type: 'iframe', 'url': IFRAME_SYNC_ONE_URL}, - {type: 'iframe', 'url': IFRAME_SYNC_TWO_URL} + { type: 'iframe', 'url': IFRAME_SYNC_ONE_URL }, + { type: 'iframe', 'url': IFRAME_SYNC_TWO_URL } ] ) }); @@ -178,7 +178,7 @@ describe('Adtrgtme Bid Adapter:', () => { expect(pixels.length).to.equal(1); expect(pixels).to.deep.equal( [ - {type: 'image', 'url': IMAGE_SYNC_URL} + { type: 'image', 'url': IMAGE_SYNC_URL } ] ) }); @@ -192,9 +192,9 @@ describe('Adtrgtme Bid Adapter:', () => { expect(pixels.length).to.equal(3); expect(pixels).to.deep.equal( [ - {type: 'image', 'url': IMAGE_SYNC_URL}, - {type: 'iframe', 'url': IFRAME_SYNC_ONE_URL}, - {type: 'iframe', 'url': IFRAME_SYNC_TWO_URL} + { type: 'image', 'url': IMAGE_SYNC_URL }, + { type: 'iframe', 'url': IFRAME_SYNC_ONE_URL }, + { type: 'iframe', 'url': IFRAME_SYNC_TWO_URL } ] ) }); @@ -203,12 +203,12 @@ describe('Adtrgtme Bid Adapter:', () => { describe('Check if bid request is OK', () => { const BAD_VALUE = [ {}, - {params: {}}, - {params: {sid: 1220291391, zid: '1836455615'}}, - {params: {sid: '1220291391', zid: 'A'}}, - {params: {sid: '', zid: '1836455615'}}, - {params: {sid: '', zid: 'A'}}, - {params: {zid: ''}}, + { params: {} }, + { params: { sid: 1220291391, zid: '1836455615' } }, + { params: { sid: '1220291391', zid: 'A' } }, + { params: { sid: '', zid: '1836455615' } }, + { params: { sid: '', zid: 'A' } }, + { params: { zid: '' } }, ]; BAD_VALUE.forEach(value => { @@ -218,10 +218,10 @@ describe('Adtrgtme Bid Adapter:', () => { }); const OK_VALUE = [ - {params: {sid: '1220291391'}}, - {params: {sid: '1220291391', zid: 1836455615}}, - {params: {sid: '1220291391', zid: '1836455615'}}, - {params: {sid: '1220291391', zid: '1836455615A'}}, + { params: { sid: '1220291391' } }, + { params: { sid: '1220291391', zid: 1836455615 } }, + { params: { sid: '1220291391', zid: '1836455615' } }, + { params: { sid: '1220291391', zid: '1836455615A' } }, ]; OK_VALUE.forEach(value => { @@ -234,7 +234,7 @@ describe('Adtrgtme Bid Adapter:', () => { describe('Bidfloor support:', () => { it('should get bidfloor from getFloor method', () => { const { bidRequest, validBR, bidderRequest } = createRequestMock({}); - bidRequest.params.bidOverride = {cur: 'AUD'}; + bidRequest.params.bidOverride = { cur: 'AUD' }; bidRequest.getFloor = (floorObj) => { return { floor: bidRequest.floors.values[floorObj.mediaType + '|300x250'], @@ -277,11 +277,11 @@ describe('Adtrgtme Bid Adapter:', () => { }); describe('Check Site obj support (ortb2):', () => { - const BAD_ORTB2_TYPES = [ null, [], 123, 'invalidID', true, false, undefined ]; + const BAD_ORTB2_TYPES = [null, [], 123, 'invalidID', true, false, undefined]; BAD_ORTB2_TYPES.forEach(key => { it(`should remove bad site data: ${JSON.stringify(key)}`, () => { const ortb2 = { site: key } - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.site[key]).to.be.undefined; }); @@ -297,7 +297,7 @@ describe('Adtrgtme Bid Adapter:', () => { [key]: 'some value here' } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.site[key]).to.exist; expect(data.site[key]).to.be.a('string'); @@ -312,7 +312,7 @@ describe('Adtrgtme Bid Adapter:', () => { [key]: ['some value here'] } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.site[key]).to.exist; expect(data.site[key]).to.be.a('array'); @@ -330,7 +330,7 @@ describe('Adtrgtme Bid Adapter:', () => { } } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.site.content[key]).to.exist; expect(data.site.content[key]).to.be.a('string'); @@ -348,7 +348,7 @@ describe('Adtrgtme Bid Adapter:', () => { } } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.site.content[key]).to.be.a('array'); expect(data.site.content[key]).to.be.equal(ortb2.site.content[key]); @@ -357,11 +357,11 @@ describe('Adtrgtme Bid Adapter:', () => { }); describe('Check ortb2 user support:', () => { - const BAD_ORTB2_TYPES = [ null, [], 'unsupportedKeyName', true, false, undefined ]; + const BAD_ORTB2_TYPES = [null, [], 'unsupportedKeyName', true, false, undefined]; BAD_ORTB2_TYPES.forEach(key => { it(`should not allow bad site types to be added to bid request: ${JSON.stringify(key)}`, () => { const ortb2 = { user: key } - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.user[key]).to.be.undefined; }); @@ -375,7 +375,7 @@ describe('Adtrgtme Bid Adapter:', () => { [key]: 'some value here' } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.user[key]).to.exist; expect(data.user[key]).to.be.a('string'); @@ -388,16 +388,16 @@ describe('Adtrgtme Bid Adapter:', () => { it(`should allow user ext to be added to the bid request: ${JSON.stringify(key)}`, () => { const ortb2 = { user: { - [key]: {a: '123', b: '456'} + [key]: { a: '123', b: '456' } } }; - const { validBR, bidderRequest } = createRequestMock({ortb2}); + const { validBR, bidderRequest } = createRequestMock({ ortb2 }); const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.user[key]).to.exist; expect(data.user[key]).to.be.a('object'); expect(data.user[key].a).to.be.equal('123'); expect(data.user[key].b).to.be.equal('456'); - config.setConfig({ortb2: {}}); + config.setConfig({ ortb2: {} }); }); }); @@ -495,7 +495,7 @@ describe('Adtrgtme Bid Adapter:', () => { it('should return a single request object for single request mode', () => { let { bidRequest, validBR, bidderRequest } = createRequestMock({}); - const { bidRequest: mock } = createRequestMock({bidId: '6heos7ks8z0j', zid: '98876543210', adUnitCode: 'bidder-code'}); + const { bidRequest: mock } = createRequestMock({ bidId: '6heos7ks8z0j', zid: '98876543210', adUnitCode: 'bidder-code' }); validBR = [bidRequest, mock]; bidderRequest.bids = validBR; @@ -584,7 +584,7 @@ describe('Adtrgtme Bid Adapter:', () => { }); it('should use siteId value as site.id', () => { - const { validBR, bidderRequest } = createRequestMock({pubIdMode: true}); + const { validBR, bidderRequest } = createRequestMock({ pubIdMode: true }); validBR[0].params.sid = '9876543210'; const data = spec.buildRequests(validBR, bidderRequest).data; expect(data.site.id).to.equal('9876543210'); @@ -608,7 +608,7 @@ describe('Adtrgtme Bid Adapter:', () => { const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.imp[0].banner).to.deep.equal({ mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'], - format: [{w: 300, h: 250}] + format: [{ w: 300, h: 250 }] }); }); @@ -620,7 +620,7 @@ describe('Adtrgtme Bid Adapter:', () => { const data = spec.buildRequests(validBR, bidderRequest)[0].data; expect(data.imp[0].banner).to.deep.equal({ mimes: ['text/html', 'text/javascript', 'application/javascript', 'image/jpg'], - format: [{w: 300, h: 250}] + format: [{ w: 300, h: 250 }] }); }); }); @@ -629,7 +629,7 @@ describe('Adtrgtme Bid Adapter:', () => { describe('for mediaTypes: "banner"', () => { it('should insert banner object into response[0].ad', () => { const { sR, bidderRequest } = createResponseMock('banner'); - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ad).to.equal(` `); expect(response[0].mediaType).to.equal('banner'); @@ -639,7 +639,7 @@ describe('Adtrgtme Bid Adapter:', () => { describe('Support adomains', () => { it('should append bid-response adomain to meta.advertiserDomains', () => { const { sR, bidderRequest } = createResponseMock('banner'); - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].meta.advertiserDomains).to.be.a('array'); expect(response[0].meta.advertiserDomains[0]).to.equal('some-advertiser-domain.com'); }) @@ -650,7 +650,7 @@ describe('Adtrgtme Bid Adapter:', () => { const { sR, bidderRequest } = createResponseMock('banner'); const adId = 'bid-response-adId'; sR.body.seatbid[0].bid[0].adId = adId; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].adId).to.equal(adId); }); @@ -658,7 +658,7 @@ describe('Adtrgtme Bid Adapter:', () => { const { sR, bidderRequest } = createResponseMock('banner'); const impid = 'y7v7iu0uljj94rbjcw9'; sR.body.seatbid[0].bid[0].impid = impid; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].adId).to.equal(impid); }); @@ -667,7 +667,7 @@ describe('Adtrgtme Bid Adapter:', () => { const crid = 'passback-12579'; sR.body.seatbid[0].bid[0].impid = undefined; sR.body.seatbid[0].bid[0].crid = crid; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].adId).to.equal(crid); }); }); @@ -680,14 +680,14 @@ describe('Adtrgtme Bid Adapter:', () => { config.setConfig({ adtrgtme: { ttl: key } }); - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ttl).to.equal(300); }); it('should not set unsupported ttl formats and check default to 300', () => { const { sR, bidderRequest } = createResponseMock('banner'); bidderRequest.bids[0].params.ttl = key; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ttl).to.equal(300); }); }); @@ -699,14 +699,14 @@ describe('Adtrgtme Bid Adapter:', () => { config.setConfig({ adtrgtme: { ttl: key } }); - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ttl).to.equal(300); }); it('should not set bad keys.ttl values', () => { const { sR, bidderRequest } = createResponseMock('banner'); bidderRequest.bids[0].params.ttl = key; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ttl).to.equal(300); }); }); @@ -717,7 +717,7 @@ describe('Adtrgtme Bid Adapter:', () => { adtrgtme: { ttl: 500 } }); bidderRequest.bids[0].params.ttl = 400; - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].ttl).to.equal(500); }); }); @@ -725,7 +725,7 @@ describe('Adtrgtme Bid Adapter:', () => { describe('Alias support', () => { it('should return undefined as the bidder code value', () => { const { sR, bidderRequest } = createResponseMock('banner'); - const response = spec.interpretResponse(sR, {bidderRequest}); + const response = spec.interpretResponse(sR, { bidderRequest }); expect(response[0].bidderCode).to.be.undefined; }); }); diff --git a/test/spec/modules/adtrueBidAdapter_spec.js b/test/spec/modules/adtrueBidAdapter_spec.js index 97e8e7cd966..cc7f20fb285 100644 --- a/test/spec/modules/adtrueBidAdapter_spec.js +++ b/test/spec/modules/adtrueBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai' -import {spec} from 'modules/adtrueBidAdapter.js' -import {newBidder} from 'src/adapters/bidderFactory.js' +import { expect } from 'chai' +import { spec } from 'modules/adtrueBidAdapter.js' +import { newBidder } from 'src/adapters/bidderFactory.js' import * as utils from '../../../src/utils.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; describe('AdTrueBidAdapter', function () { const adapter = newBidder(spec) @@ -489,14 +489,14 @@ describe('AdTrueBidAdapter', function () { sandbox.restore(); }); it('execute as per config', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, [bidResponses], undefined, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, [bidResponses], undefined, undefined)).to.deep.equal([{ type: 'iframe', url: 'https://hb.adtrue.com/prebid/usersync?bidder=adtrue&publisherId=1212&zoneId=21423&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' }]); }); // Multiple user sync output it('execute as per config', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, [bidResponses2], undefined, undefined)).to.deep.equal([ + expect(spec.getUserSyncs({ iframeEnabled: true }, [bidResponses2], undefined, undefined)).to.deep.equal([ { type: 'image', url: 'https://hb.adtrue.com/prebid/usersync?bidder=adtrue&type=image&publisherId=1212&zoneId=21423&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' diff --git a/test/spec/modules/aduptechBidAdapter_spec.js b/test/spec/modules/aduptechBidAdapter_spec.js index 2b909ebe20d..3aa297aa0e7 100644 --- a/test/spec/modules/aduptechBidAdapter_spec.js +++ b/test/spec/modules/aduptechBidAdapter_spec.js @@ -154,7 +154,7 @@ describe('AduptechBidAdapter', () => { sizes: [[12, 34], [56, 78]] }; - expect(internal.extractBannerConfig(bidRequest)).to.deep.equal({sizes: bidRequest.sizes}); + expect(internal.extractBannerConfig(bidRequest)).to.deep.equal({ sizes: bidRequest.sizes }); }); }); diff --git a/test/spec/modules/advRedAnalyticsAdapter_spec.js b/test/spec/modules/advRedAnalyticsAdapter_spec.js index fd56126d1db..fa051901c90 100644 --- a/test/spec/modules/advRedAnalyticsAdapter_spec.js +++ b/test/spec/modules/advRedAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import advRedAnalytics from 'modules/advRedAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; +import { expectEvents } from '../../helpers/analytics.js'; import { EVENTS } from 'src/constants.js'; import sinon from 'sinon'; diff --git a/test/spec/modules/advangelistsBidAdapter_spec.js b/test/spec/modules/advangelistsBidAdapter_spec.js index 4a01d375902..e8367dc143f 100755 --- a/test/spec/modules/advangelistsBidAdapter_spec.js +++ b/test/spec/modules/advangelistsBidAdapter_spec.js @@ -7,9 +7,9 @@ describe('advangelistsBidAdapter', function () { let bidRequestsVid; beforeEach(function () { - bidRequests = [{'bidder': 'advangelists', 'params': {'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'banner': {'sizes': [[300, 250]]}}, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}]; + bidRequests = [{ 'bidder': 'advangelists', 'params': { 'pubid': '0cf8d6d643e13d86a5b6374148a4afac', 'placement': 1234 }, 'crumbs': { 'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449' }, 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] } }, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': 'f72931e6-2b0e-4e37-a2bc-1ea912141f81', 'sizes': [[300, 250]], 'bidId': '2aa73f571eaf29', 'bidderRequestId': '1bac84515a7af3', 'auctionId': '5dbc60fa-1aa1-41ce-9092-e6bbd4d478f7', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com' }]; - bidRequestsVid = [{'bidder': 'advangelists', 'params': {'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234}, 'crumbs': {'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449'}, 'mediaTypes': {'video': {'playerSize': [[320, 480]], 'context': 'instream', 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30}}, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com'}]; + bidRequestsVid = [{ 'bidder': 'advangelists', 'params': { 'pubid': '8537f00948fc37cc03c5f0f88e198a76', 'placement': 1234 }, 'crumbs': { 'pubcid': '979fde13-c71e-4ac2-98b7-28c90f99b449' }, 'mediaTypes': { 'video': { 'playerSize': [[320, 480]], 'context': 'instream', 'skip': 1, 'mimes': ['video/mp4', 'application/javascript'], 'playbackmethod': [2, 6], 'maxduration': 30 } }, 'adUnitCode': 'video1', 'transactionId': '8b060952-93f7-4863-af44-bb8796b97c42', 'sizes': [], 'bidId': '25c6ab92aa0e81', 'bidderRequestId': '1d420b73a013fc', 'auctionId': '9a69741c-34fb-474c-83e1-cfa003aaee17', 'src': 'client', 'bidRequestsCount': 1, 'pageurl': 'http://google.com' }]; }); describe('spec.isBidRequestValid', function () { @@ -44,19 +44,19 @@ describe('advangelistsBidAdapter', function () { describe('spec.buildRequests', function () { it('should create a POST request for each bid', function () { const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ], { timeout: 1000 }); + const requests = spec.buildRequests([bidRequest], { timeout: 1000 }); expect(requests[0].method).to.equal('POST'); }); it('should create a POST request for each bid in video request', function () { const bidRequest = bidRequestsVid[0]; - const requests = spec.buildRequests([ bidRequest ], { timeout: 1000 }); + const requests = spec.buildRequests([bidRequest], { timeout: 1000 }); expect(requests[0].method).to.equal('POST'); }); it('should have domain in request', function () { const bidRequest = bidRequests[0]; - const requests = spec.buildRequests([ bidRequest ], { timeout: 1000 }); + const requests = spec.buildRequests([bidRequest], { timeout: 1000 }); expect(requests[0].data.site.domain).to.have.length.above(0); }); }); @@ -65,8 +65,8 @@ describe('advangelistsBidAdapter', function () { describe('for banner bids', function () { it('should return valid video bid responses', function () { const _mediaTypes = VIDEO; - const advangelistsbidreqVid = {'bidRequest': {'mediaTypes': {'video': {'w': 320, 'h': 480}}}}; - const serverResponseVid = {'cur': 'USD', 'id': '25c6ab92aa0e81', 'seatbid': [{'seat': '3', 'bid': [{'crid': '1855', 'h': 480, 'protocol': 2, 'nurl': 'http://nep.advangelists.com/xp/evt?pp=1MO1wiaMhhq7wLRzZZwwwPkJxxKpYEnM5k5MH4qSGm1HR8rp3Nl7vDocvzZzSAvE4pnREL9mQ1kf5PDjk6E8em6DOk7vVrYUH1TYQyqCucd58PFpJNN7h30RXKHHFg3XaLuQ3PKfMuI1qZATBJ6WHcu875y0hqRdiewn0J4JsCYF53M27uwmcV0HnQxARQZZ72mPqrW95U6wgkZljziwKrICM3aBV07TU6YK5R5AyzJRuD6mtrQ2xtHlQ3jXVYKE5bvWFiUQd90t0jOGhPtYBNoOfP7uQ4ZZj4pyucxbr96orHe9PSOn9UpCSWArdx7s8lOfDpwOvbMuyGxynbStDWm38sDgd4bMHnIt762m5VMDNJfiUyX0vWzp05OsufJDVEaWhAM62i40lQZo7mWP4ipoOWLkmlaAzFIMsTcNaHAHiKKqGEOZLkCEhFNM0SLcvgN2HFRULOOIZvusq7TydOKxuXgCS91dLUDxDDDFUK83BFKlMkTxnCzkLbIR1bd9GKcr1TRryOrulyvRWAKAIhEsUzsc5QWFUhmI2dZ1eqnBQJ0c89TaPcnoaP2WipF68UgyiOstf2CBy0M34858tC5PmuQwQYwXscg6zyqDwR0i9MzGH4FkTyU5yeOlPcsA0ht6UcoCdFpHpumDrLUwAaxwGk1Nj8S6YlYYT5wNuTifDGbg22QKXzZBkUARiyVvgPn9nRtXnrd7WmiMYq596rya9RQj7LC0auQW8bHVQLEe49shsZDnAwZTWr4QuYKqgRGZcXteG7RVJe0ryBZezOq11ha9C0Lv0siNVBahOXE35Wzoq4c4BDaGpqvhaKN7pjeWLGlQR04ufWekwxiMWAvjmfgAfexBJ7HfbYNZpq__', 'adid': '61_1855', 'adomain': ['chevrolet.com'], 'price': 2, 'w': 320, 'iurl': 'https://daf37cpxaja7f.cloudfront.net/c61/creative_url_14922301369663_1.png', 'cat': ['IAB2'], 'id': '7f570b40-aca1-4806-8ea8-818ea679c82b_0', 'attr': [], 'impid': '0', 'cid': '61'}]}], 'bidid': '7f570b40-aca1-4806-8ea8-818ea679c82b'}; + const advangelistsbidreqVid = { 'bidRequest': { 'mediaTypes': { 'video': { 'w': 320, 'h': 480 } } } }; + const serverResponseVid = { 'cur': 'USD', 'id': '25c6ab92aa0e81', 'seatbid': [{ 'seat': '3', 'bid': [{ 'crid': '1855', 'h': 480, 'protocol': 2, 'nurl': 'http://nep.advangelists.com/xp/evt?pp=1MO1wiaMhhq7wLRzZZwwwPkJxxKpYEnM5k5MH4qSGm1HR8rp3Nl7vDocvzZzSAvE4pnREL9mQ1kf5PDjk6E8em6DOk7vVrYUH1TYQyqCucd58PFpJNN7h30RXKHHFg3XaLuQ3PKfMuI1qZATBJ6WHcu875y0hqRdiewn0J4JsCYF53M27uwmcV0HnQxARQZZ72mPqrW95U6wgkZljziwKrICM3aBV07TU6YK5R5AyzJRuD6mtrQ2xtHlQ3jXVYKE5bvWFiUQd90t0jOGhPtYBNoOfP7uQ4ZZj4pyucxbr96orHe9PSOn9UpCSWArdx7s8lOfDpwOvbMuyGxynbStDWm38sDgd4bMHnIt762m5VMDNJfiUyX0vWzp05OsufJDVEaWhAM62i40lQZo7mWP4ipoOWLkmlaAzFIMsTcNaHAHiKKqGEOZLkCEhFNM0SLcvgN2HFRULOOIZvusq7TydOKxuXgCS91dLUDxDDDFUK83BFKlMkTxnCzkLbIR1bd9GKcr1TRryOrulyvRWAKAIhEsUzsc5QWFUhmI2dZ1eqnBQJ0c89TaPcnoaP2WipF68UgyiOstf2CBy0M34858tC5PmuQwQYwXscg6zyqDwR0i9MzGH4FkTyU5yeOlPcsA0ht6UcoCdFpHpumDrLUwAaxwGk1Nj8S6YlYYT5wNuTifDGbg22QKXzZBkUARiyVvgPn9nRtXnrd7WmiMYq596rya9RQj7LC0auQW8bHVQLEe49shsZDnAwZTWr4QuYKqgRGZcXteG7RVJe0ryBZezOq11ha9C0Lv0siNVBahOXE35Wzoq4c4BDaGpqvhaKN7pjeWLGlQR04ufWekwxiMWAvjmfgAfexBJ7HfbYNZpq__', 'adid': '61_1855', 'adomain': ['chevrolet.com'], 'price': 2, 'w': 320, 'iurl': 'https://daf37cpxaja7f.cloudfront.net/c61/creative_url_14922301369663_1.png', 'cat': ['IAB2'], 'id': '7f570b40-aca1-4806-8ea8-818ea679c82b_0', 'attr': [], 'impid': '0', 'cid': '61' }] }], 'bidid': '7f570b40-aca1-4806-8ea8-818ea679c82b' }; const bidResponseVid = spec.interpretResponse({ body: serverResponseVid }, advangelistsbidreqVid); delete bidResponseVid['vastUrl']; delete bidResponseVid['ad']; @@ -85,16 +85,17 @@ describe('advangelistsBidAdapter', function () { }); it('should return valid banner bid responses', function () { - const advangelistsbidreq = {bids: {}}; + const advangelistsbidreq = { bids: {} }; bidRequests.forEach(bid => { const _mediaTypes = (bid.mediaTypes && bid.mediaTypes.video ? VIDEO : BANNER); - advangelistsbidreq.bids[bid.bidId] = {mediaTypes: _mediaTypes, + advangelistsbidreq.bids[bid.bidId] = { + mediaTypes: _mediaTypes, w: _mediaTypes === BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][0] : bid.mediaTypes[_mediaTypes].playerSize[0], h: _mediaTypes === BANNER ? bid.mediaTypes[_mediaTypes].sizes[0][1] : bid.mediaTypes[_mediaTypes].playerSize[1] }; }); - const serverResponse = {'id': '2aa73f571eaf29', 'seatbid': [{'bid': [{'id': '2c5e8a1a84522d', 'impid': '2c5e8a1a84522d', 'price': 0.81, 'adid': 'abcde-12345', 'nurl': '', 'adm': '
', 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', 'adomain': ['chevrolet.com'], 'w': 300, 'h': 250}], 'seat': '19513bcfca8006'}], 'bidid': '19513bcfca8006', 'cur': 'USD', 'w': 300, 'h': 250}; + const serverResponse = { 'id': '2aa73f571eaf29', 'seatbid': [{ 'bid': [{ 'id': '2c5e8a1a84522d', 'impid': '2c5e8a1a84522d', 'price': 0.81, 'adid': 'abcde-12345', 'nurl': '', 'adm': '
', 'iurl': '', 'cid': 'campaign1', 'crid': 'abcde-12345', 'adomain': ['chevrolet.com'], 'w': 300, 'h': 250 }], 'seat': '19513bcfca8006' }], 'bidid': '19513bcfca8006', 'cur': 'USD', 'w': 300, 'h': 250 }; const bidResponse = spec.interpretResponse({ body: serverResponse }, advangelistsbidreq); expect(bidResponse).to.deep.equal({ diff --git a/test/spec/modules/advertisingBidAdapter_spec.js b/test/spec/modules/advertisingBidAdapter_spec.js index d9067f63826..440a15227f8 100644 --- a/test/spec/modules/advertisingBidAdapter_spec.js +++ b/test/spec/modules/advertisingBidAdapter_spec.js @@ -700,7 +700,7 @@ describe('advertisingBidAdapter ', function () { mediaTypes: { video: { context: 'instream', - playerSize: [[ 640, 480 ]], + playerSize: [[640, 480]], startdelay: 1, linearity: 1, plcmt: 1, @@ -709,7 +709,7 @@ describe('advertisingBidAdapter ', function () { }, adUnitCode: 'video1', transactionId: '93e5def8-29aa-4fe8-bd3a-0298c39f189a', - sizes: [[ 640, 480 ]], + sizes: [[640, 480]], bidId: '2624fabbb078e8', bidderRequestId: '117954d20d7c9c', auctionId: 'defd525f-4f1e-4416-a4cb-ae53be90e706', diff --git a/test/spec/modules/adverxoBidAdapter_spec.js b/test/spec/modules/adverxoBidAdapter_spec.js index 8dea5e3a326..676f7126c94 100644 --- a/test/spec/modules/adverxoBidAdapter_spec.js +++ b/test/spec/modules/adverxoBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/adverxoBidAdapter.js'; -import {config} from 'src/config'; +import { expect } from 'chai'; +import { spec } from 'modules/adverxoBidAdapter.js'; +import { config } from 'src/config'; describe('Adverxo Bid Adapter', () => { function makeBidRequestWithParams(params) { @@ -8,7 +8,7 @@ describe('Adverxo Bid Adapter', () => { bidId: '2e9f38ea93bb9e', bidder: 'adverxo', adUnitCode: 'adunit-code', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: params, bidderRequestId: 'test-bidder-request-id' }; @@ -26,7 +26,7 @@ describe('Adverxo Bid Adapter', () => { 'id': '01EAJWWNEPN3CYMM5N8M5VXY22' }] }], - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { host: 'bid.example.com', adUnitId: 1, @@ -48,17 +48,17 @@ describe('Adverxo Bid Adapter', () => { { id: 1, required: 1, - img: {type: 3, w: 150, h: 50} + img: { type: 3, w: 150, h: 50 } }, { id: 2, required: 1, - title: {len: 80} + title: { len: 80 } }, { id: 3, required: 0, - data: {type: 1} + data: { type: 1 } } ] }; @@ -246,7 +246,7 @@ describe('Adverxo Bid Adapter', () => { const bidRequests = [ { bidder: 'bidsmind', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { adUnitId: 1, auth: 'authExample', @@ -269,7 +269,7 @@ describe('Adverxo Bid Adapter', () => { const bidRequests = [ { bidder: 'adverxo', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { adUnitId: 1, auth: 'authExample', @@ -311,19 +311,19 @@ describe('Adverxo Bid Adapter', () => { expect(nativeRequest.assets[0]).to.deep.equal({ id: 1, required: 1, - img: {w: 150, h: 50, type: 3} + img: { w: 150, h: 50, type: 3 } }); expect(nativeRequest.assets[1]).to.deep.equal({ id: 2, required: 1, - title: {len: 80} + title: { len: 80 } }); expect(nativeRequest.assets[2]).to.deep.equal({ id: 3, required: 0, - data: {type: 1} + data: { type: 1 } }); }); } @@ -359,7 +359,7 @@ describe('Adverxo Bid Adapter', () => { it('should add bid floor to request', function () { const bannerBidRequestWithFloor = { ...bannerBidRequests[0], - getFloor: () => ({currency: 'USD', floor: 3}) + getFloor: () => ({ currency: 'USD', floor: 3 }) }; const request = spec.buildRequests([bannerBidRequestWithFloor], {})[0].data; @@ -505,11 +505,11 @@ describe('Adverxo Bid Adapter', () => { native: { ortb: { assets: [ - {id: 2, title: {text: 'Title'}}, - {id: 3, data: {value: 'Description'}}, - {id: 1, img: {url: 'http://example.com?img', w: 150, h: 50}} + { id: 2, title: { text: 'Title' } }, + { id: 3, data: { value: 'Description' } }, + { id: 1, img: { url: 'http://example.com?img', w: 150, h: 50 } } ], - link: {url: 'http://example.com?link'} + link: { url: 'http://example.com?link' } } } } @@ -646,14 +646,14 @@ describe('Adverxo Bid Adapter', () => { describe('getUserSyncs', () => { const exampleUrl = 'https://example.com/usync?id=5'; - const iframeConfig = {iframeEnabled: true}; + const iframeConfig = { iframeEnabled: true }; const responses = [{ - body: {ext: {avx_usync: [exampleUrl]}} + body: { ext: { avx_usync: [exampleUrl] } } }]; const responseWithoutQueryString = [{ - body: {ext: {avx_usync: ['https://example.com/usync/sf/5']}} + body: { ext: { avx_usync: ['https://example.com/usync/sf/5'] } } }]; it('should not return empty list if not allowed', function () { @@ -685,17 +685,17 @@ describe('Adverxo Bid Adapter', () => { }); it('should add GDPR parameters if provided', function () { - expect(spec.getUserSyncs(iframeConfig, responses, {gdprApplies: true}, undefined, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs(iframeConfig, responses, { gdprApplies: true }, undefined, undefined)).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe&gdpr=1&gdpr_consent=` }]); expect(spec.getUserSyncs(iframeConfig, responses, - {gdprApplies: true, consentString: 'foo?'}, undefined, undefined)).to.deep.equal([{ + { gdprApplies: true, consentString: 'foo?' }, undefined, undefined)).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe&gdpr=1&gdpr_consent=foo%3F` }]); expect(spec.getUserSyncs(iframeConfig, responses, - {gdprApplies: false, consentString: 'bar'}, undefined, undefined)).to.deep.equal([{ + { gdprApplies: false, consentString: 'bar' }, undefined, undefined)).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe&gdpr=0&gdpr_consent=bar` }]); }); @@ -707,7 +707,7 @@ describe('Adverxo Bid Adapter', () => { }); it('should not apply if not gppConsent.gppString', function () { - const gppConsent = {gppString: '', applicableSections: [123]}; + const gppConsent = { gppString: '', applicableSections: [123] }; const result = spec.getUserSyncs(iframeConfig, responses, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe` @@ -715,7 +715,7 @@ describe('Adverxo Bid Adapter', () => { }); it('should not apply if not gppConsent.applicableSections', function () { - const gppConsent = {gppString: '', applicableSections: undefined}; + const gppConsent = { gppString: '', applicableSections: undefined }; const result = spec.getUserSyncs(iframeConfig, responses, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe` @@ -723,7 +723,7 @@ describe('Adverxo Bid Adapter', () => { }); it('should not apply if empty gppConsent.applicableSections', function () { - const gppConsent = {gppString: '', applicableSections: []}; + const gppConsent = { gppString: '', applicableSections: [] }; const result = spec.getUserSyncs(iframeConfig, responses, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe` @@ -731,7 +731,7 @@ describe('Adverxo Bid Adapter', () => { }); it('should apply if all above are available', function () { - const gppConsent = {gppString: 'foo?', applicableSections: [123]}; + const gppConsent = { gppString: 'foo?', applicableSections: [123] }; const result = spec.getUserSyncs(iframeConfig, responses, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe&gpp=foo%3F&gpp_sid=123` @@ -739,7 +739,7 @@ describe('Adverxo Bid Adapter', () => { }); it('should support multiple sections', function () { - const gppConsent = {gppString: 'foo', applicableSections: [123, 456]}; + const gppConsent = { gppString: 'foo', applicableSections: [123, 456] }; const result = spec.getUserSyncs(iframeConfig, responses, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `${exampleUrl}&type=iframe&gpp=foo&gpp_sid=123%2C456` diff --git a/test/spec/modules/adxcgBidAdapter_spec.js b/test/spec/modules/adxcgBidAdapter_spec.js index 0f14bad94ce..885a1d2a7bf 100644 --- a/test/spec/modules/adxcgBidAdapter_spec.js +++ b/test/spec/modules/adxcgBidAdapter_spec.js @@ -1,10 +1,10 @@ // jshint esversion: 6, es3: false, node: true /* eslint dot-notation:0, quote-props:0 */ -import {assert, expect} from 'chai'; -import {spec} from 'modules/adxcgBidAdapter.js'; -import {config} from 'src/config.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/adxcgBidAdapter.js'; +import { config } from 'src/config.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; const utils = require('src/utils'); diff --git a/test/spec/modules/adyoulikeBidAdapter_spec.js b/test/spec/modules/adyoulikeBidAdapter_spec.js index 337bd6fea75..e3a8f223256 100644 --- a/test/spec/modules/adyoulikeBidAdapter_spec.js +++ b/test/spec/modules/adyoulikeBidAdapter_spec.js @@ -19,8 +19,8 @@ describe('Adyoulike Adapter', function () { consentString: consentString, gdprApplies: true }, - refererInfo: {location: referrerUrl, canonicalUrl, domain, topmostLocation: 'fakePageURL'}, - ortb2: {site: {page: pageUrl, ref: referrerUrl}} + refererInfo: { location: referrerUrl, canonicalUrl, domain, topmostLocation: 'fakePageURL' }, + ortb2: { site: { page: pageUrl, ref: referrerUrl } } }; const bidRequestWithEmptyPlacement = [ { @@ -30,9 +30,9 @@ describe('Adyoulike Adapter', function () { 'params': {}, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250', '300x600'] - } + { + 'banner': + { 'sizes': ['300x250', '300x600'] } } } ]; @@ -64,39 +64,40 @@ describe('Adyoulike Adapter', function () { }, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - }, - 'native': - { 'image': { - 'required': true, - }, - 'title': { - 'required': true, - 'len': 80 - }, - 'cta': { - 'required': false - }, - 'sponsoredBy': { - 'required': true - }, - 'clickUrl': { - 'required': true - }, - 'privacyIcon': { - 'required': false - }, - 'privacyLink': { - 'required': false - }, - 'body': { - 'required': true - }, - 'icon': { - 'required': true, - 'sizes': [] - } + { + 'banner': + { 'sizes': ['300x250'] }, + 'native': + { + 'image': { + 'required': true, + }, + 'title': { + 'required': true, + 'len': 80 + }, + 'cta': { + 'required': false + }, + 'sponsoredBy': { + 'required': true + }, + 'clickUrl': { + 'required': true + }, + 'privacyIcon': { + 'required': false + }, + 'privacyLink': { + 'required': false + }, + 'body': { + 'required': true + }, + 'icon': { + 'required': true, + 'sizes': [] + } }, }, 'ortb2': { @@ -178,7 +179,7 @@ describe('Adyoulike Adapter', function () { { 'video': { 'context': 'instream', - 'playerSize': [[ 640, 480 ]] + 'playerSize': [[640, 480]] } }, ortb2Imp: { @@ -309,9 +310,9 @@ describe('Adyoulike Adapter', function () { }, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } + { + 'banner': + { 'sizes': ['300x250'] } }, ortb2Imp: { ext: { @@ -331,9 +332,9 @@ describe('Adyoulike Adapter', function () { }, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } + { + 'banner': + { 'sizes': ['300x250'] } }, ortb2Imp: { ext: { @@ -350,9 +351,9 @@ describe('Adyoulike Adapter', function () { }, 'sizes': [[300, 600]], 'mediaTypes': - { 'banner': - {'sizes': ['300x600'] - } + { + 'banner': + { 'sizes': ['300x600'] } }, ortb2Imp: { ext: { @@ -389,7 +390,8 @@ describe('Adyoulike Adapter', function () { const requestDataOnePlacement = { 'bid_id_0': - { 'PlacementID': 'e622af275681965d3095808561a1e510', + { + 'PlacementID': 'e622af275681965d3095808561a1e510', 'TransactionID': '1bca18cc-c0fe-439b-88c2-8247d3448f22', 'Width': 300, 'Height': 600, @@ -399,14 +401,16 @@ describe('Adyoulike Adapter', function () { const requestDataMultiPlacement = { 'bid_id_0': - { 'PlacementID': 'e622af275681965d3095808561a1e510', + { + 'PlacementID': 'e622af275681965d3095808561a1e510', 'TransactionID': '1bca18cc-c0fe-439b-88c2-8247d3448f22', 'Width': 300, 'Height': 600, 'AvailableSizes': '300x600' }, 'bid_id_1': - { 'PlacementID': 'e622af275681965d3095808561a1e510', + { + 'PlacementID': 'e622af275681965d3095808561a1e510', 'TransactionID': 'e63b2d86-ca60-4167-9cf1-497607079634', 'Width': 400, 'Height': 250, @@ -746,11 +750,11 @@ describe('Adyoulike Adapter', function () { expect(payload.Bids['bid_id_0'].PlacementID).to.be.equal('placement_0'); expect(payload.PageRefreshed).to.equal(false); expect(payload.Bids['bid_id_0'].TransactionID).to.be.equal('bid_id_0_transaction_id'); - expect(payload.ortb2).to.deep.equal({site: {page: pageUrl, ref: referrerUrl}}); + expect(payload.ortb2).to.deep.equal({ site: { page: pageUrl, ref: referrerUrl } }); }); it('sends bid request to endpoint with single placement without canonical', function () { - const request = spec.buildRequests(bidRequestWithSinglePlacement, {...bidderRequest, refererInfo: {...bidderRequest.refererInfo, canonicalUrl: null}}); + const request = spec.buildRequests(bidRequestWithSinglePlacement, { ...bidderRequest, refererInfo: { ...bidderRequest.refererInfo, canonicalUrl: null } }); const payload = JSON.parse(request.data); expect(request.url).to.contain(getEndpoint()); @@ -765,7 +769,7 @@ describe('Adyoulike Adapter', function () { }); it('sends bid request to endpoint with single placement multiple mediatype', function () { - const request = spec.buildRequests(bidRequestWithSinglePlacement, {...bidderRequest, refererInfo: {...bidderRequest.refererInfo, canonicalUrl: null}}); + const request = spec.buildRequests(bidRequestWithSinglePlacement, { ...bidderRequest, refererInfo: { ...bidderRequest.refererInfo, canonicalUrl: null } }); const payload = JSON.parse(request.data); expect(request.url).to.contain(getEndpoint()); @@ -837,7 +841,7 @@ describe('Adyoulike Adapter', function () { it('receive reponse with single placement', function () { serverResponse.body = responseWithSinglePlacement; - const result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(requestDataOnePlacement) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"Bids":' + JSON.stringify(requestDataOnePlacement) + '}' }); expect(result.length).to.equal(1); expect(result[0].cpm).to.equal(0.5); @@ -849,7 +853,7 @@ describe('Adyoulike Adapter', function () { it('receive reponse with multiple placement', function () { serverResponse.body = responseWithMultiplePlacements; - const result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(requestDataMultiPlacement) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"Bids":' + JSON.stringify(requestDataMultiPlacement) + '}' }); expect(result.length).to.equal(2); @@ -866,7 +870,7 @@ describe('Adyoulike Adapter', function () { it('receive reponse with Native from ad markup', function () { serverResponse.body = responseWithSinglePlacement; - const result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(sentBidNative) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"Bids":' + JSON.stringify(sentBidNative) + '}' }); expect(result.length).to.equal(1); @@ -875,7 +879,7 @@ describe('Adyoulike Adapter', function () { it('receive reponse with Native ad', function () { serverResponse.body = responseWithSingleNative; - const result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(sentBidNative) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"Bids":' + JSON.stringify(sentBidNative) + '}' }); expect(result.length).to.equal(1); @@ -890,7 +894,7 @@ describe('Adyoulike Adapter', function () { it('receive Vast reponse with Video ad', function () { serverResponse.body = responseWithSingleVideo; - const result = spec.interpretResponse(serverResponse, {data: '{"Bids":' + JSON.stringify(sentBidVideo) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"Bids":' + JSON.stringify(sentBidVideo) + '}' }); expect(result.length).to.equal(1); expect(result).to.deep.equal(videoResult); @@ -916,14 +920,14 @@ describe('Adyoulike Adapter', function () { }); it('should add GDPR parameters if provided', function() { - expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs(userSyncConfig, {}, { gdprApplies: true, consentString: undefined }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=` }]); - expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: 'foo?'}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs(userSyncConfig, {}, { gdprApplies: true, consentString: 'foo?' }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}&gdpr=1&gdpr_consent=foo%3F` }]); - expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: false, consentString: 'bar'}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs(userSyncConfig, {}, { gdprApplies: false, consentString: 'bar' }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}&gdpr=0&gdpr_consent=bar` }]); }); @@ -1007,7 +1011,7 @@ describe('Adyoulike Adapter', function () { it('should return empty list of syncs', function() { expect(spec.getUserSyncs(userSyncConfig, {}, undefined, undefined)).to.deep.equal(emptySync); - expect(spec.getUserSyncs(userSyncConfig, {}, {gdprApplies: true, consentString: 'foo'}, 'bar')).to.deep.equal(emptySync); + expect(spec.getUserSyncs(userSyncConfig, {}, { gdprApplies: true, consentString: 'foo' }, 'bar')).to.deep.equal(emptySync); }); }); }); diff --git a/test/spec/modules/afpBidAdapter_spec.js b/test/spec/modules/afpBidAdapter_spec.js index 48c9fc1c701..7efebcaebc5 100644 --- a/test/spec/modules/afpBidAdapter_spec.js +++ b/test/spec/modules/afpBidAdapter_spec.js @@ -32,8 +32,8 @@ const sizes = [[imageWidth, imageHeight]] const bidderRequest = { refererInfo: { referer: pageUrl }, } -const mediaTypeBanner = { [BANNER]: {sizes: [[imageWidth, imageHeight]]} } -const mediaTypeVideo = { [VIDEO]: {playerSize: [[imageWidth, imageHeight]]} } +const mediaTypeBanner = { [BANNER]: { sizes: [[imageWidth, imageHeight]] } } +const mediaTypeVideo = { [VIDEO]: { playerSize: [[imageWidth, imageHeight]] } } const commonParams = { placeId, placeContainer, @@ -117,7 +117,7 @@ const configByPlaceType = { }) }, } -const getTransformedConfig = ({mediaTypes, params}) => { +const getTransformedConfig = ({ mediaTypes, params }) => { return { params: params, sizes, diff --git a/test/spec/modules/aidemBidAdapter_spec.js b/test/spec/modules/aidemBidAdapter_spec.js index 979d2cb922f..52654465f82 100644 --- a/test/spec/modules/aidemBidAdapter_spec.js +++ b/test/spec/modules/aidemBidAdapter_spec.js @@ -1,10 +1,10 @@ -import {expect} from 'chai'; -import {setEndPoints, spec} from 'modules/aidemBidAdapter.js'; +import { expect } from 'chai'; +import { setEndPoints, spec } from 'modules/aidemBidAdapter.js'; import * as utils from '../../../src/utils.js'; -import {deepSetValue} from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; -import {config} from '../../../src/config.js'; -import {NATIVE} from '../../../src/mediaTypes.js'; +import { deepSetValue } from '../../../src/utils.js'; +import { server } from '../../mocks/xhr.js'; +import { config } from '../../../src/config.js'; +import { NATIVE } from '../../../src/mediaTypes.js'; // Full banner + Full Video + Basic Banner + Basic Video const VALID_BIDS = [ @@ -161,8 +161,8 @@ const DEFAULT_VALID_BANNER_REQUESTS = [ mediaTypes: { banner: { sizes: [ - [ 300, 250 ], - [ 300, 600 ] + [300, 250], + [300, 600] ] } }, @@ -448,7 +448,7 @@ describe('Aidem adapter', () => { }); it('should have a well formatted banner payload', () => { - const {data} = spec.buildRequests(DEFAULT_VALID_BANNER_REQUESTS, VALID_BIDDER_REQUEST); + const { data } = spec.buildRequests(DEFAULT_VALID_BANNER_REQUESTS, VALID_BIDDER_REQUEST); expect(data).to.be.a('object').that.has.all.keys( 'id', 'imp', 'regs', 'site', 'environment', 'at', 'test' ) @@ -464,7 +464,7 @@ describe('Aidem adapter', () => { if (FEATURES.VIDEO) { it('should have a well formatted video payload', () => { - const {data} = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST); + const { data } = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST); expect(data).to.be.a('object').that.has.all.keys( 'id', 'imp', 'regs', 'site', 'environment', 'at', 'test' ) @@ -480,7 +480,7 @@ describe('Aidem adapter', () => { } it('should hav wpar keys in environment object', function () { - const {data} = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST); + const { data } = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST); expect(data).to.have.property('environment') expect(data.environment).to.be.a('object').that.have.property('wpar') expect(data.environment.wpar).to.be.a('object').that.has.keys('innerWidth', 'innerHeight') @@ -489,8 +489,8 @@ describe('Aidem adapter', () => { describe('interpretResponse', () => { it('should return a valid bid array with a banner bid', () => { - const {data} = spec.buildRequests(DEFAULT_VALID_BANNER_REQUESTS, VALID_BIDDER_REQUEST) - const bids = spec.interpretResponse({body: SERVER_RESPONSE_BANNER}, { data }) + const { data } = spec.buildRequests(DEFAULT_VALID_BANNER_REQUESTS, VALID_BIDDER_REQUEST) + const bids = spec.interpretResponse({ body: SERVER_RESPONSE_BANNER }, { data }) expect(bids).to.be.a('array').that.has.lengthOf(1) bids.forEach(value => { expect(value).to.be.a('object').that.has.all.keys( @@ -501,8 +501,8 @@ describe('Aidem adapter', () => { if (FEATURES.VIDEO) { it('should return a valid bid array with a video bid', () => { - const {data} = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST) - const bids = spec.interpretResponse({body: SERVER_RESPONSE_VIDEO}, { data }) + const { data } = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST) + const bids = spec.interpretResponse({ body: SERVER_RESPONSE_VIDEO }, { data }) expect(bids).to.be.a('array').that.has.lengthOf(1) bids.forEach(value => { expect(value).to.be.a('object').that.has.all.keys( @@ -513,8 +513,8 @@ describe('Aidem adapter', () => { } it('should return a valid bid array with netRevenue', () => { - const {data} = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST) - const bids = spec.interpretResponse({body: SERVER_RESPONSE_VIDEO}, { data }) + const { data } = spec.buildRequests(DEFAULT_VALID_VIDEO_REQUESTS, VALID_BIDDER_REQUEST) + const bids = spec.interpretResponse({ body: SERVER_RESPONSE_VIDEO }, { data }) expect(bids).to.be.a('array').that.has.lengthOf(1) expect(bids[0].netRevenue).to.be.true }); diff --git a/test/spec/modules/airgridRtdProvider_spec.js b/test/spec/modules/airgridRtdProvider_spec.js index 3e885dbe55d..5c6c43a93eb 100644 --- a/test/spec/modules/airgridRtdProvider_spec.js +++ b/test/spec/modules/airgridRtdProvider_spec.js @@ -1,5 +1,5 @@ -import {config} from 'src/config.js'; -import {deepAccess} from 'src/utils.js'; +import { config } from 'src/config.js'; +import { deepAccess } from 'src/utils.js'; import * as agRTD from 'modules/airgridRtdProvider.js'; import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js'; @@ -78,7 +78,7 @@ describe('airgrid RTD Submodule', function () { const bidderOrtb2 = {}; - agRTD.setAudiencesAsBidderOrtb2({ortb2Fragments: {bidder: bidderOrtb2}}, RTD_CONFIG.dataProviders[0], audiences); + agRTD.setAudiencesAsBidderOrtb2({ ortb2Fragments: { bidder: bidderOrtb2 } }, RTD_CONFIG.dataProviders[0], audiences); const bidders = RTD_CONFIG.dataProviders[0].params.bidders diff --git a/test/spec/modules/ajaBidAdapter_spec.js b/test/spec/modules/ajaBidAdapter_spec.js index b9acda490e9..37a68934ed9 100644 --- a/test/spec/modules/ajaBidAdapter_spec.js +++ b/test/spec/modules/ajaBidAdapter_spec.js @@ -54,9 +54,9 @@ describe('AjaAdapter', function () { version: ['8', '0', '0'] }, browsers: [ - {brand: 'Not_A Brand', version: ['99', '0', '0', '0']}, - {brand: 'Google Chrome', version: ['109', '0', '5414', '119']}, - {brand: 'Chromium', version: ['109', '0', '5414', '119']} + { brand: 'Not_A Brand', version: ['99', '0', '0', '0'] }, + { brand: 'Google Chrome', version: ['109', '0', '5414', '119'] }, + { brand: 'Chromium', version: ['109', '0', '5414', '119'] } ], mobile: 1, model: 'SM-G955U', @@ -206,7 +206,7 @@ describe('AjaAdapter', function () { ]; let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); @@ -217,7 +217,7 @@ describe('AjaAdapter', function () { }; let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); }); diff --git a/test/spec/modules/allegroBidAdapter_spec.js b/test/spec/modules/allegroBidAdapter_spec.js index 59f5ed1018d..5575f17a358 100644 --- a/test/spec/modules/allegroBidAdapter_spec.js +++ b/test/spec/modules/allegroBidAdapter_spec.js @@ -1,16 +1,16 @@ -import {expect} from 'chai'; -import {spec} from 'modules/allegroBidAdapter.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/allegroBidAdapter.js'; +import { config } from 'src/config.js'; import sinon from 'sinon'; import * as utils from 'src/utils.js'; -function buildBidRequest({bidId = 'bid1', adUnitCode = 'div-1', sizes = [[300, 250]], params = {}, mediaTypes} = {}) { +function buildBidRequest({ bidId = 'bid1', adUnitCode = 'div-1', sizes = [[300, 250]], params = {}, mediaTypes } = {}) { return { bidId, adUnitCode, bidder: 'allegro', params, - mediaTypes: mediaTypes || {banner: {sizes}}, + mediaTypes: mediaTypes || { banner: { sizes } }, }; } @@ -20,11 +20,11 @@ function buildBidderRequest(bidRequests, ortb2Overrides = {}) { bids: bidRequests, auctionId: 'auc-1', timeout: 1000, - refererInfo: {page: 'https://example.com', domain: 'example.com', ref: '', stack: ['https://example.com']}, + refererInfo: { page: 'https://example.com', domain: 'example.com', ref: '', stack: ['https://example.com'] }, ortb2: Object.assign({ device: { dnt: 0, - sua: {mobile: 0} + sua: { mobile: 0 } } }, ortb2Overrides) }; @@ -79,12 +79,12 @@ describe('Allegro Bid Adapter', () => { configStub = sinon.stub(config, 'getConfig').callsFake((key) => undefined); const bidRequests = [buildBidRequest({})]; const ortb2 = { - site: {ext: {siteCustom: 'val'}, publisher: {ext: {pubCustom: 'pub'}}}, - user: {ext: {userCustom: 'usr'}, data: [{ext: {dataCustom: 'd1'}}]}, - device: {ext: {deviceCustom: 'dev'}, sua: {mobile: 1}, dnt: 1}, - regs: {ext: {gdpr: 1, other: 'x'}}, - source: {ext: {sourceCustom: 'src'}}, - ext: {requestCustom: 'req'} + site: { ext: { siteCustom: 'val' }, publisher: { ext: { pubCustom: 'pub' } } }, + user: { ext: { userCustom: 'usr' }, data: [{ ext: { dataCustom: 'd1' } }] }, + device: { ext: { deviceCustom: 'dev' }, sua: { mobile: 1 }, dnt: 1 }, + regs: { ext: { gdpr: 1, other: 'x' } }, + source: { ext: { sourceCustom: 'src' } }, + ext: { requestCustom: 'req' } }; const bidderRequest = buildBidderRequest(bidRequests, ortb2); const req = spec.buildRequests(bidRequests, bidderRequest); @@ -109,7 +109,7 @@ describe('Allegro Bid Adapter', () => { return undefined; }); const bidRequests = [buildBidRequest({})]; - const ortb2 = {site: {ext: {siteCustom: 'val'}}}; + const ortb2 = { site: { ext: { siteCustom: 'val' } } }; const req = spec.buildRequests(bidRequests, buildBidderRequest(bidRequests, ortb2)); expect(req.data.site.ext.siteCustom).to.equal('val'); expect(req.data.site['[com.google.doubleclick.site]']).to.equal(undefined); @@ -117,7 +117,7 @@ describe('Allegro Bid Adapter', () => { it('converts numeric flags to booleans (topframe, secure, test) when present', () => { configStub = sinon.stub(config, 'getConfig').callsFake((key) => undefined); - const bidRequests = [buildBidRequest({mediaTypes: {banner: {sizes: [[300, 250]], topframe: 1}}, params: {secure: 1}})]; + const bidRequests = [buildBidRequest({ mediaTypes: { banner: { sizes: [[300, 250]], topframe: 1 } }, params: { secure: 1 } })]; const bidderRequest = buildBidderRequest(bidRequests); // add test flag via ortb2 without clobbering existing device object bidderRequest.ortb2.test = 1; @@ -134,13 +134,13 @@ describe('Allegro Bid Adapter', () => { describe('interpretResponse', () => { it('returns undefined for empty body', () => { - const result = spec.interpretResponse({}, {data: {}}); + const result = spec.interpretResponse({}, { data: {} }); expect(result).to.equal(undefined); }); it('returns converted bids for a valid ORTB response', () => { configStub = sinon.stub(config, 'getConfig').callsFake((key) => undefined); - const bidRequests = [buildBidRequest({bidId: 'imp-1'})]; + const bidRequests = [buildBidRequest({ bidId: 'imp-1' })]; const bidderRequest = buildBidderRequest(bidRequests); const built = spec.buildRequests(bidRequests, bidderRequest); const impId = built.data.imp[0].id; // use actual id from converter @@ -148,10 +148,10 @@ describe('Allegro Bid Adapter', () => { id: 'resp1', seatbid: [{ seat: 'seat1', - bid: [{impid: impId, price: 1.23, crid: 'creative1', w: 300, h: 250}] + bid: [{ impid: impId, price: 1.23, crid: 'creative1', w: 300, h: 250 }] }] }; - const result = spec.interpretResponse({body: ortbResponse}, built); + const result = spec.interpretResponse({ body: ortbResponse }, built); expect(result).to.be.an('array').with.lengthOf(1); const bid = result[0]; expect(bid.cpm).to.equal(1.23); @@ -162,13 +162,13 @@ describe('Allegro Bid Adapter', () => { it('ignores bids with impid not present in original request', () => { configStub = sinon.stub(config, 'getConfig').callsFake((key) => undefined); - const bidRequests = [buildBidRequest({bidId: 'imp-1'})]; + const bidRequests = [buildBidRequest({ bidId: 'imp-1' })]; const bidderRequest = buildBidderRequest(bidRequests); const built = spec.buildRequests(bidRequests, bidderRequest); const ortbResponse = { - seatbid: [{seat: 'seat1', bid: [{impid: 'unknown', price: 0.5, crid: 'x'}]}] + seatbid: [{ seat: 'seat1', bid: [{ impid: 'unknown', price: 0.5, crid: 'x' }] }] }; - const result = spec.interpretResponse({body: ortbResponse}, built); + const result = spec.interpretResponse({ body: ortbResponse }, built); expect(result).to.be.an('array').that.is.empty; }); }); @@ -179,7 +179,7 @@ describe('Allegro Bid Adapter', () => { if (key === 'allegro.triggerImpressionPixel') return false; return undefined; }); - const bid = {burl: 'https://example.com/win?price=${AUCTION_PRICE}', cpm: 1.2}; + const bid = { burl: 'https://example.com/win?price=${AUCTION_PRICE}', cpm: 1.2 }; expect(spec.onBidWon(bid)).to.equal(undefined); }); diff --git a/test/spec/modules/ampliffyBidAdapter_spec.js b/test/spec/modules/ampliffyBidAdapter_spec.js index 4c1a170477d..195bbf6e5d8 100644 --- a/test/spec/modules/ampliffyBidAdapter_spec.js +++ b/test/spec/modules/ampliffyBidAdapter_spec.js @@ -6,9 +6,9 @@ import { mergeParams, paramsToQueryString, setCurrentURL } from 'modules/ampliffyBidAdapter.js'; -import {expect} from 'chai'; -import {BANNER, VIDEO} from 'src/mediaTypes'; -import {newBidder} from 'src/adapters/bidderFactory'; +import { expect } from 'chai'; +import { BANNER, VIDEO } from 'src/mediaTypes'; +import { newBidder } from 'src/adapters/bidderFactory'; describe('Ampliffy bid adapter Test', function () { const adapter = newBidder(spec); @@ -240,8 +240,8 @@ describe('Ampliffy bid adapter Test', function () { 'adnetwork': 'ampliffy.com', 'SERVER': 'bidder.ampliffy.com' }, - 'crumbs': {'pubcid': '29844d69-c4e5-4b00-8602-6dd09815363a'}, - 'ortb2Imp': {'ext': {'data': {'pbadslot': 'video1'}}}, + 'crumbs': { 'pubcid': '29844d69-c4e5-4b00-8602-6dd09815363a' }, + 'ortb2Imp': { 'ext': { 'data': { 'pbadslot': 'video1' } } }, 'mediaTypes': { 'video': { 'context': 'instream', @@ -285,8 +285,8 @@ describe('Ampliffy bid adapter Test', function () { 'adnetwork': 'ampliffy.com', 'SERVER': 'bidder.ampliffy.com' }, - 'crumbs': {'pubcid': '29844d69-c4e5-4b00-8602-6dd09815363a'}, - 'ortb2Imp': {'ext': {'data': {'pbadslot': 'video1'}}}, + 'crumbs': { 'pubcid': '29844d69-c4e5-4b00-8602-6dd09815363a' }, + 'ortb2Imp': { 'ext': { 'data': { 'pbadslot': 'video1' } } }, 'mediaTypes': { 'video': { 'context': 'instream', @@ -335,8 +335,8 @@ describe('Ampliffy bid adapter Test', function () { ] } }, - ortb2Imp: {ext: {}}, - params: {placementId: 13144370}, + ortb2Imp: { ext: {} }, + params: { placementId: 13144370 }, sizes: [ [300, 250], [300, 600] @@ -344,7 +344,7 @@ describe('Ampliffy bid adapter Test', function () { src: 'client', transactionId: '103b2b58-6ed1-45e9-9486-c942d6042e3' }, - data: {bidId: '2d40b8dcd02ade'}, + data: { bidId: '2d40b8dcd02ade' }, method: 'GET', url: 'https://test.com', }; diff --git a/test/spec/modules/amxBidAdapter_spec.js b/test/spec/modules/amxBidAdapter_spec.js index 1328a28e438..a44b427a478 100644 --- a/test/spec/modules/amxBidAdapter_spec.js +++ b/test/spec/modules/amxBidAdapter_spec.js @@ -7,7 +7,7 @@ import { server } from 'test/mocks/xhr.js'; import * as utils from 'src/utils.js'; import { getGlobal } from '../../../src/prebidGlobal.js'; -import {getGlobalVarName} from '../../../src/buildOptions.js'; +import { getGlobalVarName } from '../../../src/buildOptions.js'; const sampleRequestId = '82c91e127a9b93e'; const sampleDisplayAd = ``; diff --git a/test/spec/modules/amxIdSystem_spec.js b/test/spec/modules/amxIdSystem_spec.js index eaeb372d730..628220d0aa9 100644 --- a/test/spec/modules/amxIdSystem_spec.js +++ b/test/spec/modules/amxIdSystem_spec.js @@ -1,9 +1,9 @@ import { amxIdSubmodule, storage } from 'modules/amxIdSystem.js'; import { server } from 'test/mocks/xhr.js'; import * as utils from 'src/utils.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; const TEST_ID = '51b561e3-0d82-4aea-8487-093fffca4a3a'; const ERROR_CODES = [404, 501, 500, 403]; diff --git a/test/spec/modules/anonymisedRtdProvider_spec.js b/test/spec/modules/anonymisedRtdProvider_spec.js index 91d3fe1bfd3..1dc7e0df8d4 100644 --- a/test/spec/modules/anonymisedRtdProvider_spec.js +++ b/test/spec/modules/anonymisedRtdProvider_spec.js @@ -1,5 +1,5 @@ -import {config} from 'src/config.js'; -import {getRealTimeData, anonymisedRtdSubmodule, storage} from 'modules/anonymisedRtdProvider.js'; +import { config } from 'src/config.js'; +import { getRealTimeData, anonymisedRtdSubmodule, storage } from 'modules/anonymisedRtdProvider.js'; import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js'; describe('anonymisedRtdProvider', function() { diff --git a/test/spec/modules/anyclipBidAdapter_spec.js b/test/spec/modules/anyclipBidAdapter_spec.js index a25c285e6c4..9ef9ae84bc9 100644 --- a/test/spec/modules/anyclipBidAdapter_spec.js +++ b/test/spec/modules/anyclipBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/anyclipBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/anyclipBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; const ENDPOINT = 'https://prebid.anyclip.com'; @@ -49,12 +49,12 @@ defaultRequestVideo.mediaTypes = { const videoBidderRequest = { bidderCode: 'anyclip', - bids: [{mediaTypes: {video: {}}, bidId: 'qwerty'}] + bids: [{ mediaTypes: { video: {} }, bidId: 'qwerty' }] }; const displayBidderRequest = { bidderCode: 'anyclip', - bids: [{bidId: 'qwerty'}] + bids: [{ bidId: 'qwerty' }] }; describe('anyclipBidAdapter', () => { @@ -109,7 +109,7 @@ describe('anyclipBidAdapter', () => { expect(request).to.have.property('transactionId').and.to.equal(defaultRequest.ortb2Imp.ext.tid); expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -203,7 +203,7 @@ describe('anyclipBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0].env; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -219,8 +219,8 @@ describe('anyclipBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -272,7 +272,7 @@ describe('anyclipBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -281,7 +281,7 @@ describe('anyclipBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['anyclip']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['anyclip'] }); }); it('should interpret valid banner response', function () { @@ -302,7 +302,7 @@ describe('anyclipBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -328,7 +328,7 @@ describe('anyclipBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: videoBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: videoBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -344,12 +344,12 @@ describe('anyclipBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -368,7 +368,7 @@ describe('anyclipBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -387,7 +387,7 @@ describe('anyclipBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -411,20 +411,20 @@ describe('anyclipBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -432,7 +432,7 @@ describe('anyclipBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -440,7 +440,7 @@ describe('anyclipBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/apesterBidAdapter_spec.js b/test/spec/modules/apesterBidAdapter_spec.js new file mode 100644 index 00000000000..f33ea20880b --- /dev/null +++ b/test/spec/modules/apesterBidAdapter_spec.js @@ -0,0 +1,774 @@ +import { expect } from 'chai'; +import { + spec as adapter, + createDomain, + storage, +} from 'modules/apesterBidAdapter'; +import * as utils from 'src/utils.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; +import { + hashCode, + extractPID, + extractCID, + extractSubDomain, + getStorageItem, + setStorageItem, + tryParseJSON, + getUniqueDealId, +} from '../../../libraries/vidazooUtils/bidderUtils.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; + +export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; + +const SUB_DOMAIN = 'exchange'; + +const BID = { + 'bidId': '2d52001cabd527', + 'adUnitCode': 'div-gpt-ad-12345-0', + 'params': { + 'subDomain': SUB_DOMAIN, + 'cId': '59db6b3b4ffaa70004f45cdc', + 'pId': '59ac17c192832d0011283fe3', + 'bidFloor': 0.1, + 'ext': { + 'param1': 'loremipsum', + 'param2': 'dolorsitamet' + } + }, + 'placementCode': 'div-gpt-ad-1460505748561-0', + 'transactionId': 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', + 'sizes': [[300, 250], [300, 600]], + 'bidderRequestId': '1fdb5ff1b6eaa7', + 'auctionId': 'auction_id', + 'bidRequestsCount': 4, + 'bidderRequestsCount': 3, + 'bidderWinsCount': 1, + 'requestId': 'b0777d85-d061-450e-9bc7-260dd54bbb7a', + 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', + 'mediaTypes': [BANNER], + 'ortb2Imp': { + 'ext': { + 'gpid': '0123456789' + } + } +}; + +const VIDEO_BID = { + 'bidId': '2d52001cabd527', + 'adUnitCode': '63550ad1ff6642d368cba59dh5884270560', + 'bidderRequestId': '12a8ae9ada9c13', + 'transactionId': '56e184c6-bde9-497b-b9b9-cf47a61381ee', + 'auctionId': 'auction_id', + 'bidRequestsCount': 4, + 'bidderRequestsCount': 3, + 'bidderWinsCount': 1, + 'schain': 'a0819c69-005b-41ed-af06-1be1e0aefefc', + 'params': { + 'subDomain': SUB_DOMAIN, + 'cId': '635509f7ff6642d368cb9837', + 'pId': '59ac17c192832d0011283fe3', + 'bidFloor': 0.1 + }, + 'sizes': [[545, 307]], + 'mediaTypes': { + 'video': { + 'playerSize': [[545, 307]], + 'context': 'instream', + 'mimes': [ + 'video/mp4', + 'application/javascript' + ], + 'protocols': [2, 3, 5, 6], + 'maxduration': 60, + 'minduration': 0, + 'startdelay': 0, + 'linearity': 1, + 'api': [2], + 'placement': 1 + } + } +} + +const ORTB2_DEVICE = { + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + w: 980, + h: 1720, + dnt: 0, + ua: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/125.0.6422.80 Mobile/15E148 Safari/604.1', + language: 'en', + devicetype: 1, + make: 'Apple', + model: 'iPhone 12 Pro Max', + os: 'iOS', + osv: '17.4', + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, +}; + +const BIDDER_REQUEST = { + 'gdprConsent': { + 'consentString': 'consent_string', + 'gdprApplies': true + }, + 'gppString': 'gpp_string', + 'gppSid': [7], + 'uspConsent': 'consent_string', + 'refererInfo': { + 'page': 'https://www.greatsite.com', + 'ref': 'https://www.somereferrer.com' + }, + 'ortb2': { + 'site': { + 'content': { + 'language': 'en' + } + }, + 'regs': { + 'gpp': 'gpp_string', + 'gpp_sid': [7], + 'coppa': 0 + }, + 'device': ORTB2_DEVICE, + } +}; + +const SERVER_RESPONSE = { + body: { + cid: 'testcid123', + results: [{ + 'ad': '', + 'price': 0.8, + 'creativeId': '12610997325162499419', + 'exp': 30, + 'width': 300, + 'height': 250, + 'advertiserDomains': ['securepubads.g.doubleclick.net'], + 'cookies': [{ + 'src': 'https://sync.com', + 'type': 'iframe' + }, { + 'src': 'https://sync.com', + 'type': 'img' + }] + }] + } +}; + +const VIDEO_SERVER_RESPONSE = { + body: { + 'cid': '635509f7ff6642d368cb9837', + 'results': [{ + 'ad': '', + 'advertiserDomains': ['bidder.apester.com'], + 'exp': 60, + 'width': 545, + 'height': 307, + 'mediaType': 'video', + 'creativeId': '12610997325162499419', + 'price': 2, + 'cookies': [] + }] + } +}; + +const ORTB2_OBJ = { + "device": ORTB2_DEVICE, + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } +}; + +const REQUEST = { + data: { + width: 300, + height: 250, + bidId: '2d52001cabd527' + } +}; + +function getTopWindowQueryParams() { + try { + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); + return parsedUrl.search; + } catch (e) { + return ''; + } +} + +describe('apesterBidAdapter', function () { + before(() => config.resetConfig()); + after(() => config.resetConfig()); + + describe('validate spec', function () { + it('exists and is a function', function () { + expect(adapter.isBidRequestValid).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.buildRequests).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.interpretResponse).to.exist.and.to.be.a('function'); + }); + + it('exists and is a function', function () { + expect(adapter.getUserSyncs).to.exist.and.to.be.a('function'); + }); + + it('exists and is a string', function () { + expect(adapter.code).to.exist.and.to.be.a('string'); + }); + + it('exists and contains media types', function () { + expect(adapter.supportedMediaTypes).to.exist.and.to.be.an('array').with.length(2); + expect(adapter.supportedMediaTypes).to.contain.members([BANNER, VIDEO]); + }); + }); + + describe('validate bid requests', function () { + it('should require cId', function () { + const isValid = adapter.isBidRequestValid({ + params: { + pId: 'pid' + } + }); + expect(isValid).to.be.false; + }); + + it('should require pId', function () { + const isValid = adapter.isBidRequestValid({ + params: { + cId: 'cid' + } + }); + expect(isValid).to.be.false; + }); + + it('should validate correctly', function () { + const isValid = adapter.isBidRequestValid({ + params: { + cId: 'cid', + pId: 'pid' + } + }); + expect(isValid).to.be.true; + }); + }); + + describe('build requests', function () { + let sandbox; + before(function () { + getGlobal().bidderSettings = { + apester: { + storageAllowed: true + } + }; + sandbox = sinon.createSandbox(); + sandbox.stub(Date, 'now').returns(1000); + }); + + it('should build video request', function () { + const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); + config.setConfig({ + bidderTimeout: 3000 + }); + const requests = adapter.buildRequests([VIDEO_BID], BIDDER_REQUEST); + expect(requests).to.have.length(1); + expect(requests[0]).to.deep.equal({ + method: 'POST', + url: `${createDomain(SUB_DOMAIN)}/prebid/multi/635509f7ff6642d368cb9837`, + data: { + adUnitCode: '63550ad1ff6642d368cba59dh5884270560', + bidFloor: 0.1, + bidId: '2d52001cabd527', + bidderVersion: adapter.version, + bidderRequestId: '12a8ae9ada9c13', + cb: 1000, + gdpr: 1, + gdprConsent: 'consent_string', + usPrivacy: 'consent_string', + gppString: 'gpp_string', + gppSid: [7], + prebidVersion: version, + transactionId: '56e184c6-bde9-497b-b9b9-cf47a61381ee', + auctionId: 'auction_id', + bidRequestsCount: 4, + bidderRequestsCount: 3, + bidderWinsCount: 1, + bidderTimeout: 3000, + publisherId: '59ac17c192832d0011283fe3', + url: 'https%3A%2F%2Fwww.greatsite.com', + referrer: 'https://www.somereferrer.com', + res: `${window.top.screen.width}x${window.top.screen.height}`, + schain: VIDEO_BID.schain, + sizes: ['545x307'], + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + device: ORTB2_DEVICE, + uniqueDealId: `${hashUrl}_${Date.now().toString()}`, + uqs: getTopWindowQueryParams(), + mediaTypes: { + video: { + api: [2], + context: 'instream', + linearity: 1, + maxduration: 60, + mimes: [ + 'video/mp4', + 'application/javascript' + ], + minduration: 0, + placement: 1, + playerSize: [[545, 307]], + protocols: [2, 3, 5, 6], + startdelay: 0 + } + }, + gpid: '', + cat: [], + contentLang: 'en', + contentData: [], + isStorageAllowed: true, + pagecat: [], + ortb2: ORTB2_OBJ, + userData: [], + coppa: 0 + } + }); + }); + + it('should build banner request for each size', function () { + const hashUrl = hashCode(BIDDER_REQUEST.refererInfo.page); + config.setConfig({ + bidderTimeout: 3000 + }); + const requests = adapter.buildRequests([BID], BIDDER_REQUEST); + expect(requests).to.have.length(1); + expect(requests[0]).to.deep.equal({ + method: 'POST', + url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`, + data: { + gdprConsent: 'consent_string', + gdpr: 1, + gppString: 'gpp_string', + gppSid: [7], + usPrivacy: 'consent_string', + transactionId: 'c881914b-a3b5-4ecf-ad9c-1c2f37c6aabf', + auctionId: 'auction_id', + bidRequestsCount: 4, + bidderRequestsCount: 3, + bidderWinsCount: 1, + bidderTimeout: 3000, + bidderRequestId: '1fdb5ff1b6eaa7', + sizes: ['300x250', '300x600'], + sua: { + 'source': 2, + 'platform': { + 'brand': 'Android', + 'version': ['8', '0', '0'] + }, + 'browsers': [ + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } + ], + 'mobile': 1, + 'model': 'SM-G955U', + 'bitness': '64', + 'architecture': '' + }, + device: ORTB2_DEVICE, + url: 'https%3A%2F%2Fwww.greatsite.com', + referrer: 'https://www.somereferrer.com', + cb: 1000, + bidFloor: 0.1, + bidId: '2d52001cabd527', + adUnitCode: 'div-gpt-ad-12345-0', + publisherId: '59ac17c192832d0011283fe3', + uniqueDealId: `${hashUrl}_${Date.now().toString()}`, + bidderVersion: adapter.version, + prebidVersion: version, + schain: BID.schain, + res: `${window.top.screen.width}x${window.top.screen.height}`, + mediaTypes: [BANNER], + gpid: '0123456789', + uqs: getTopWindowQueryParams(), + 'ext.param1': 'loremipsum', + 'ext.param2': 'dolorsitamet', + cat: [], + contentLang: 'en', + contentData: [], + isStorageAllowed: true, + pagecat: [], + ortb2Imp: BID.ortb2Imp, + ortb2: ORTB2_OBJ, + userData: [], + coppa: 0 + } + }); + }); + + after(function () { + getGlobal().bidderSettings = {}; + sandbox.restore(); + }); + }); + describe('getUserSyncs', function () { + it('should have valid user sync with iframeEnabled', function () { + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.apester.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' + }]); + }); + + it('should have valid user sync with cid on response', function () { + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.apester.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' + }]); + }); + + it('should have valid user sync with pixelEnabled', function () { + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); + + expect(result).to.deep.equal([{ + 'url': 'https://sync.apester.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', + 'type': 'image' + }]); + }); + + it('should have valid user sync with coppa on response', function () { + config.setConfig({ + coppa: 1 + }); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); + expect(result).to.deep.equal([{ + type: 'iframe', + url: 'https://sync.apester.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' + }]); + }); + + it('should generate url with consent data', function () { + const gdprConsent = { + gdprApplies: true, + consentString: 'consent_string' + }; + const uspConsent = 'usp_string'; + const gppConsent = { + gppString: 'gpp_string', + applicableSections: [7] + } + + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + + expect(result).to.deep.equal([{ + 'url': 'https://sync.apester.com/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', + 'type': 'image' + }]); + }); + }); + + describe('interpret response', function () { + it('should return empty array when there is no response', function () { + const responses = adapter.interpretResponse(null); + expect(responses).to.be.empty; + }); + + it('should return empty array when there is no ad', function () { + const responses = adapter.interpretResponse({ price: 1, ad: '' }); + expect(responses).to.be.empty; + }); + + it('should return empty array when there is no price', function () { + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); + expect(responses).to.be.empty; + }); + + it('should return an array of interpreted banner responses', function () { + const responses = adapter.interpretResponse(SERVER_RESPONSE, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0]).to.deep.equal({ + requestId: '2d52001cabd527', + cpm: 0.8, + width: 300, + height: 250, + creativeId: '12610997325162499419', + currency: 'USD', + netRevenue: true, + ttl: 30, + ad: '', + meta: { + advertiserDomains: ['securepubads.g.doubleclick.net'] + } + }); + }); + + it('should get meta from response metaData', function () { + const serverResponse = utils.deepClone(SERVER_RESPONSE); + serverResponse.body.results[0].metaData = { + advertiserDomains: ['bidder.apester.com'], + agencyName: 'Agency Name', + }; + const responses = adapter.interpretResponse(serverResponse, REQUEST); + expect(responses[0].meta).to.deep.equal({ + advertiserDomains: ['bidder.apester.com'], + agencyName: 'Agency Name' + }); + }); + + it('should return an array of interpreted video responses', function () { + const responses = adapter.interpretResponse(VIDEO_SERVER_RESPONSE, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0]).to.deep.equal({ + requestId: '2d52001cabd527', + cpm: 2, + width: 545, + height: 307, + mediaType: 'video', + creativeId: '12610997325162499419', + currency: 'USD', + netRevenue: true, + ttl: 60, + vastXml: '', + meta: { + advertiserDomains: ['bidder.apester.com'] + } + }); + }); + + it('should take default TTL', function () { + const serverResponse = utils.deepClone(SERVER_RESPONSE); + delete serverResponse.body.results[0].exp; + const responses = adapter.interpretResponse(serverResponse, REQUEST); + expect(responses).to.have.length(1); + expect(responses[0].ttl).to.equal(300); + }); + }); + + describe('user id system', function () { + TEST_ID_SYSTEMS.forEach((idSystemProvider) => { + const id = Date.now().toString(); + const bid = utils.deepClone(BID); + + const userId = (function () { + switch (idSystemProvider) { + case 'lipb': + return { lipbid: id }; + case 'id5id': + return { uid: id }; + default: + return id; + } + })(); + + bid.userId = { + [idSystemProvider]: userId + }; + + it(`should include 'uid.${idSystemProvider}' in request params`, function () { + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data[`uid.${idSystemProvider}`]).to.equal(id); + }); + }); + // testing bid.userIdAsEids handling + it("should include user ids from bid.userIdAsEids (length=1)", function() { + const bid = utils.deepClone(BID); + bid.userIdAsEids = [ + { + "source": "audigent.com", + "uids": [{ "id": "fakeidi6j6dlc6e" }] + } + ] + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e"); + }) + it("should include user ids from bid.userIdAsEids (length=2)", function() { + const bid = utils.deepClone(BID); + bid.userIdAsEids = [ + { + "source": "audigent.com", + "uids": [{ "id": "fakeidi6j6dlc6e" }] + }, + { + "source": "rwdcntrl.net", + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] + } + ] + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.audigent.com']).to.equal("fakeidi6j6dlc6e"); + expect(requests[0].data['uid.rwdcntrl.net']).to.equal("fakeid6f35197d5c"); + }) + // testing user.ext.eid handling + it("should include user ids from user.ext.eid (length=1)", function() { + const bid = utils.deepClone(BID); + bid.user = { + ext: { + eids: [ + { + "source": "pubcid.org", + "uids": [{ "id": "fakeid8888dlc6e" }] + } + ] + } + } + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e"); + }) + it("should include user ids from user.ext.eid (length=2)", function() { + const bid = utils.deepClone(BID); + bid.user = { + ext: { + eids: [ + { + "source": "pubcid.org", + "uids": [{ "id": "fakeid8888dlc6e" }] + }, + { + "source": "adserver.org", + "uids": [{ "id": "fakeid495ff1" }] + } + ] + } + } + const requests = adapter.buildRequests([bid], BIDDER_REQUEST); + expect(requests[0].data['uid.pubcid.org']).to.equal("fakeid8888dlc6e"); + expect(requests[0].data['uid.adserver.org']).to.equal("fakeid495ff1"); + }) + }); + + describe('alternate param names extractors', function () { + it('should return undefined when param not supported', function () { + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); + expect(cid).to.be.undefined; + expect(pid).to.be.undefined; + expect(subDomain).to.be.undefined; + }); + + it('should return value when param supported', function () { + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); + expect(cid).to.be.equal('1'); + expect(pid).to.be.equal('2'); + expect(subDomain).to.be.equal('prebid'); + }); + }); + + describe('unique deal id', function () { + before(function () { + getGlobal().bidderSettings = { + apester: { + storageAllowed: true + } + }; + }); + after(function () { + getGlobal().bidderSettings = {}; + }); + const key = 'myKey'; + let uniqueDealId; + beforeEach(() => { + uniqueDealId = getUniqueDealId(storage, key, 0); + }) + + it('should get current unique deal id', function (done) { + // waiting some time so `now` will become past + setTimeout(() => { + const current = getUniqueDealId(storage, key); + expect(current).to.be.equal(uniqueDealId); + done(); + }, 200); + }); + + it('should get new unique deal id on expiration', function (done) { + setTimeout(() => { + const current = getUniqueDealId(storage, key, 100); + expect(current).to.not.be.equal(uniqueDealId); + done(); + }, 200) + }); + }); + + describe('storage utils', function () { + before(function () { + getGlobal().bidderSettings = { + apester: { + storageAllowed: true + } + }; + }); + after(function () { + getGlobal().bidderSettings = {}; + }); + it('should get value from storage with create param', function () { + const now = Date.now(); + const clock = useFakeTimers({ + shouldAdvanceTime: true, + now + }); + setStorageItem(storage, 'myKey', 2020); + const { value, created } = getStorageItem(storage, 'myKey'); + expect(created).to.be.equal(now); + expect(value).to.be.equal(2020); + expect(typeof value).to.be.equal('number'); + expect(typeof created).to.be.equal('number'); + clock.restore(); + }); + + it('should get external stored value', function () { + const value = 'superman' + window.localStorage.setItem('myExternalKey', value); + const item = getStorageItem(storage, 'myExternalKey'); + expect(item).to.be.equal(value); + }); + + it('should parse JSON value', function () { + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); + expect(event).to.be.equal('send'); + }); + + it('should get original value on parse fail', function () { + const value = 21; + const parsed = tryParseJSON(value); + expect(typeof parsed).to.be.equal('number'); + expect(parsed).to.be.equal(value); + }); + }); +}); diff --git a/test/spec/modules/appStockSSPBidAdapter_spec.js b/test/spec/modules/appStockSSPBidAdapter_spec.js index 7ee7d739dd3..64dac5fe8e7 100644 --- a/test/spec/modules/appStockSSPBidAdapter_spec.js +++ b/test/spec/modules/appStockSSPBidAdapter_spec.js @@ -499,7 +499,7 @@ describe('AppStockSSPBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -508,9 +508,7 @@ describe('AppStockSSPBidAdapter', function () { expect(syncData[0].url).to.equal('https://csync.al-ad.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -519,7 +517,7 @@ describe('AppStockSSPBidAdapter', function () { expect(syncData[0].url).to.equal('https://csync.al-ad.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/appierAnalyticsAdapter_spec.js b/test/spec/modules/appierAnalyticsAdapter_spec.js index e380672b73c..3e7ad334384 100644 --- a/test/spec/modules/appierAnalyticsAdapter_spec.js +++ b/test/spec/modules/appierAnalyticsAdapter_spec.js @@ -2,7 +2,7 @@ import { appierAnalyticsAdapter, getCpmInUsd, parseBidderCode, parseAdUnitCode, ANALYTICS_VERSION, BIDDER_STATUS } from 'modules/appierAnalyticsAdapter.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; const events = require('src/events'); const constants = require('src/constants.js'); @@ -122,7 +122,7 @@ describe('Appier Prebid AnalyticsAdapter Testing', function () { }); describe('#getCachedAuction()', function() { - const existing = {timeoutBids: [{}]}; + const existing = { timeoutBids: [{}] }; appierAnalyticsAdapter.cachedAuctions['test_auction_id'] = existing; it('should get the existing cached object if it exists', function() { diff --git a/test/spec/modules/appierBidAdapter_spec.js b/test/spec/modules/appierBidAdapter_spec.js index 93f95fbd182..0b295b7c609 100644 --- a/test/spec/modules/appierBidAdapter_spec.js +++ b/test/spec/modules/appierBidAdapter_spec.js @@ -137,7 +137,7 @@ describe('AppierAdapter', function () { describe('getApiServer', function() { it('should use the server specified by setConfig(appier.server)', function() { config.setConfig({ - 'appier': {'server': 'fake_server'} + 'appier': { 'server': 'fake_server' } }); const server = spec.getApiServer(); @@ -147,7 +147,7 @@ describe('AppierAdapter', function () { it('should retrieve a farm specific hostname if server is not specpfied', function() { config.setConfig({ - 'appier': {'farm': 'tw'} + 'appier': { 'farm': 'tw' } }); const server = spec.getApiServer(); @@ -157,7 +157,7 @@ describe('AppierAdapter', function () { it('if farm is not recognized, use the default farm', function() { config.setConfig({ - 'appier': {'farm': 'no_this_farm'} + 'appier': { 'farm': 'no_this_farm' } }); const server = spec.getApiServer(); diff --git a/test/spec/modules/appnexusBidAdapter_spec.js b/test/spec/modules/appnexusBidAdapter_spec.js index f4a00bfb264..2c5d279c7bb 100644 --- a/test/spec/modules/appnexusBidAdapter_spec.js +++ b/test/spec/modules/appnexusBidAdapter_spec.js @@ -5,7 +5,7 @@ import { auctionManager } from 'src/auctionManager.js'; import { deepClone } from 'src/utils.js'; import * as utils from 'src/utils.js'; import { config } from 'src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; diff --git a/test/spec/modules/apstreamBidAdapter_spec.js b/test/spec/modules/apstreamBidAdapter_spec.js index de13e45b6b9..723ac11b962 100644 --- a/test/spec/modules/apstreamBidAdapter_spec.js +++ b/test/spec/modules/apstreamBidAdapter_spec.js @@ -1,9 +1,9 @@ // jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/apstreamBidAdapter.js'; +import { assert, expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/apstreamBidAdapter.js'; import * as utils from 'src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const validBidRequests = [{ bidId: 'bidId', @@ -60,7 +60,7 @@ describe('AP Stream adapter', function() { }); it('should return false when publisherId is configured and two media types', function() { - bid.mediaTypes.video = {sizes: [300, 250]}; + bid.mediaTypes.video = { sizes: [300, 250] }; assert.isFalse(spec.isBidRequestValid(bid)) }); @@ -76,7 +76,7 @@ describe('AP Stream adapter', function() { const request = spec.buildRequests(validBidRequests, { })[0]; assert.equal(request.method, 'GET'); - assert.deepEqual(request.options, {withCredentials: false}); + assert.deepEqual(request.options, { withCredentials: false }); assert.ok(request.data); }); diff --git a/test/spec/modules/asoBidAdapter_spec.js b/test/spec/modules/asoBidAdapter_spec.js index e0fffee68d8..304d7add0ba 100644 --- a/test/spec/modules/asoBidAdapter_spec.js +++ b/test/spec/modules/asoBidAdapter_spec.js @@ -1,9 +1,9 @@ -import {expect} from 'chai'; -import {spec} from 'modules/asoBidAdapter.js'; -import {BANNER, NATIVE, VIDEO} from 'src/mediaTypes.js'; -import {OUTSTREAM} from 'src/video.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {parseUrl} from '../../../src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/asoBidAdapter.js'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes.js'; +import { OUTSTREAM } from 'src/video.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { parseUrl } from '../../../src/utils.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; @@ -381,8 +381,8 @@ describe('Adserver.Online bidding adapter', function () { crid: 123, adm: JSON.stringify({ assets: [ - {id: 0, title: {text: 'Title'}}, - {id: 1, img: {type: 3, url: 'https://img'}}, + { id: 0, title: { text: 'Title' } }, + { id: 1, img: { type: 3, url: 'https://img' } }, ], }), adomain: ['example.com'], diff --git a/test/spec/modules/asteriobidAnalyticsAdapter_spec.js b/test/spec/modules/asteriobidAnalyticsAdapter_spec.js index e8a1cca534b..54106f4ed48 100644 --- a/test/spec/modules/asteriobidAnalyticsAdapter_spec.js +++ b/test/spec/modules/asteriobidAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import asteriobidAnalytics, {storage} from 'modules/asteriobidAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; +import asteriobidAnalytics, { storage } from 'modules/asteriobidAnalyticsAdapter.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; import * as utils from 'src/utils.js'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expectEvents } from '../../helpers/analytics.js'; import { EVENTS } from 'src/constants.js'; const events = require('src/events'); diff --git a/test/spec/modules/atsAnalyticsAdapter_spec.js b/test/spec/modules/atsAnalyticsAdapter_spec.js index c294a5e08d0..43c9f612256 100644 --- a/test/spec/modules/atsAnalyticsAdapter_spec.js +++ b/test/spec/modules/atsAnalyticsAdapter_spec.js @@ -1,12 +1,12 @@ -import atsAnalyticsAdapter, {parseBrowser, analyticsUrl, bidRequestedHandler} from '../../../modules/atsAnalyticsAdapter.js'; +import atsAnalyticsAdapter, { parseBrowser, analyticsUrl, bidRequestedHandler } from '../../../modules/atsAnalyticsAdapter.js'; import { expect } from 'chai'; import adapterManager from 'src/adapterManager.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; -import {getCoreStorageManager, getStorageManager} from '../../../src/storageManager.js'; +import { getCoreStorageManager, getStorageManager } from '../../../src/storageManager.js'; -import {EVENTS} from 'src/constants.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { EVENTS } from 'src/constants.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const utils = require('src/utils'); const events = require('src/events'); @@ -299,7 +299,7 @@ describe('ats analytics adapter', function () { 'bidId': '30c77d079cdf17', 'userIdAsEids': [{ 'source': 'liveramp.com', - 'uids': [{'id': 'AmThEbO1ssIWjrNdU4noT4ZFBILSVBBYHbipOYt_JP40e5nZdXns2g'}] + 'uids': [{ 'id': 'AmThEbO1ssIWjrNdU4noT4ZFBILSVBBYHbipOYt_JP40e5nZdXns2g' }] }] }], 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7' @@ -337,7 +337,7 @@ describe('ats analytics adapter', function () { 'bidId': '30c77d079cdf17', 'userIdAsEids': [{ 'source': 'id5-sync.com', - 'uids': [{'id': 'some-other-id'}] + 'uids': [{ 'id': 'some-other-id' }] }] }], 'auctionId': 'a5b849e5-87d7-4205-8300-d063084fcfb7' @@ -461,15 +461,15 @@ describe('ats analytics adapter', function () { 'userIdAsEids': [ { 'source': 'id5-sync.com', - 'uids': [{'id': 'id5-value'}] + 'uids': [{ 'id': 'id5-value' }] }, { 'source': 'liveramp.com', - 'uids': [{'id': 'liveramp-value'}] + 'uids': [{ 'id': 'liveramp-value' }] }, { 'source': 'criteo.com', - 'uids': [{'id': 'criteo-value'}] + 'uids': [{ 'id': 'criteo-value' }] } ] }], diff --git a/test/spec/modules/automatadAnalyticsAdapter_spec.js b/test/spec/modules/automatadAnalyticsAdapter_spec.js index 9a7e6b13a6e..4f203da09de 100644 --- a/test/spec/modules/automatadAnalyticsAdapter_spec.js +++ b/test/spec/modules/automatadAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import * as events from 'src/events'; import * as utils from 'src/utils.js'; -import spec, {self as exports} from 'modules/automatadAnalyticsAdapter.js'; +import spec, { self as exports } from 'modules/automatadAnalyticsAdapter.js'; import { EVENTS } from 'src/constants.js'; import { expect } from 'chai'; @@ -154,47 +154,47 @@ describe('Automatad Analytics Adapter', () => { }) it('Should call the auctionInitHandler when the auction init event is fired', () => { - events.emit(AUCTION_INIT, {type: AUCTION_INIT}) + events.emit(AUCTION_INIT, { type: AUCTION_INIT }) expect(global.window.atmtdAnalytics.auctionInitHandler.called).to.equal(true) }); it('Should call the bidRequested when the bidRequested event is fired', () => { - events.emit(BID_REQUESTED, {type: BID_REQUESTED}) + events.emit(BID_REQUESTED, { type: BID_REQUESTED }) expect(global.window.atmtdAnalytics.bidRequestedHandler.called).to.equal(true) }); it('Should call the bidRejected when the bidRejected event is fired', () => { - events.emit(BID_REJECTED, {type: BID_REJECTED}) + events.emit(BID_REJECTED, { type: BID_REJECTED }) expect(global.window.atmtdAnalytics.bidRejectedHandler.called).to.equal(true) }); it('Should call the bidResponseHandler when the bidResponse event is fired', () => { - events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + events.emit(BID_RESPONSE, { type: BID_RESPONSE }) expect(global.window.atmtdAnalytics.bidResponseHandler.called).to.equal(true) }); it('Should call the bidderDoneHandler when the bidderDone event is fired', () => { - events.emit(BIDDER_DONE, {type: BIDDER_DONE}) + events.emit(BIDDER_DONE, { type: BIDDER_DONE }) expect(global.window.atmtdAnalytics.bidderDoneHandler.called).to.equal(true) }); it('Should call the bidWonHandler when the bidWon event is fired', () => { - events.emit(BID_WON, {type: BID_WON}) + events.emit(BID_WON, { type: BID_WON }) expect(global.window.atmtdAnalytics.bidWonHandler.called).to.equal(true) }); it('Should call the noBidHandler when the noBid event is fired', () => { - events.emit(NO_BID, {type: NO_BID}) + events.emit(NO_BID, { type: NO_BID }) expect(global.window.atmtdAnalytics.noBidHandler.called).to.equal(true) }); it('Should call the bidTimeoutHandler when the bidTimeout event is fired', () => { - events.emit(BID_TIMEOUT, {type: BID_TIMEOUT}) + events.emit(BID_TIMEOUT, { type: BID_TIMEOUT }) expect(global.window.atmtdAnalytics.bidderTimeoutHandler.called).to.equal(true) }); it('Should call the auctionDebugHandler when the auctionDebug event is fired', () => { - events.emit(AUCTION_DEBUG, {type: AUCTION_DEBUG}) + events.emit(AUCTION_DEBUG, { type: AUCTION_DEBUG }) expect(global.window.atmtdAnalytics.auctionDebugHandler.called).to.equal(true) }); }); @@ -223,7 +223,7 @@ describe('Automatad Analytics Adapter', () => { }) it('Should push to the que when the auctionInit event is fired', () => { - events.emit(AUCTION_INIT, {type: AUCTION_INIT}) + events.emit(AUCTION_INIT, { type: AUCTION_INIT }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -232,7 +232,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidResponse event is fired', () => { - events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + events.emit(BID_RESPONSE, { type: BID_RESPONSE }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -241,7 +241,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidRequested event is fired', () => { - events.emit(BID_REQUESTED, {type: BID_REQUESTED}) + events.emit(BID_REQUESTED, { type: BID_REQUESTED }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -250,7 +250,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidRejected event is fired', () => { - events.emit(BID_REJECTED, {type: BID_REJECTED}) + events.emit(BID_REJECTED, { type: BID_REJECTED }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -259,7 +259,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidderDone event is fired', () => { - events.emit(BIDDER_DONE, {type: BIDDER_DONE}) + events.emit(BIDDER_DONE, { type: BIDDER_DONE }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -268,7 +268,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidWon event is fired', () => { - events.emit(BID_WON, {type: BID_WON}) + events.emit(BID_WON, { type: BID_WON }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -277,7 +277,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the noBid event is fired', () => { - events.emit(NO_BID, {type: NO_BID}) + events.emit(NO_BID, { type: NO_BID }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -286,7 +286,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the auctionDebug is fired', () => { - events.emit(AUCTION_DEBUG, {type: AUCTION_DEBUG}) + events.emit(AUCTION_DEBUG, { type: AUCTION_DEBUG }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -295,7 +295,7 @@ describe('Automatad Analytics Adapter', () => { }); it('Should push to the que when the bidderTimeout event is fired', () => { - events.emit(BID_TIMEOUT, {type: BID_TIMEOUT}) + events.emit(BID_TIMEOUT, { type: BID_TIMEOUT }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -331,7 +331,7 @@ describe('Automatad Analytics Adapter', () => { }) it('Should push to the que when the auctionInit event is fired and push to the que even after SDK has loaded after auctionInit event', () => { - events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + events.emit(BID_RESPONSE, { type: BID_RESPONSE }) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(1) expect(exports.__atmtdAnalyticsQueue[0]).to.have.lengthOf(2) @@ -340,7 +340,7 @@ describe('Automatad Analytics Adapter', () => { expect(exports.qBeingUsed).to.equal(true) expect(exports.qTraversalComplete).to.equal(undefined) global.window.atmtdAnalytics = obj - events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + events.emit(BID_RESPONSE, { type: BID_RESPONSE }) expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) expect(exports.__atmtdAnalyticsQueue[1]).to.have.lengthOf(2) @@ -352,8 +352,8 @@ describe('Automatad Analytics Adapter', () => { it('Should push to the que when the auctionInit event is fired and push to the analytics adapter handler after the que is processed', () => { expect(exports.qBeingUsed).to.equal(undefined) - events.emit(AUCTION_INIT, {type: AUCTION_INIT}) - global.window.atmtdAnalytics = {...obj} + events.emit(AUCTION_INIT, { type: AUCTION_INIT }) + global.window.atmtdAnalytics = { ...obj } const handlers = global.window.atmtdAnalytics Object.keys(handlers).forEach((handler) => global.window.atmtdAnalytics[handler].resetHistory()) expect(exports.__atmtdAnalyticsQueue.push.called).to.equal(true) @@ -367,13 +367,13 @@ describe('Automatad Analytics Adapter', () => { clock.tick(2000) expect(exports.qBeingUsed).to.equal(true) expect(exports.qTraversalComplete).to.equal(undefined) - events.emit(NO_BID, {type: NO_BID}) + events.emit(NO_BID, { type: NO_BID }) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) clock.tick(1500) expect(exports.qBeingUsed).to.equal(false) expect(exports.qTraversalComplete).to.equal(true) - events.emit(BID_RESPONSE, {type: BID_RESPONSE}) + events.emit(BID_RESPONSE, { type: BID_RESPONSE }) expect(exports.__atmtdAnalyticsQueue).to.be.an('array').to.have.lengthOf(2) expect(exports.__atmtdAnalyticsQueue.push.calledTwice).to.equal(true) expect(exports.__atmtdAnalyticsQueue.push.calledThrice).to.equal(false) @@ -419,7 +419,7 @@ describe('Automatad Analytics Adapter', () => { it('Should retry processing auctionInit in certain intervals', () => { expect(exports.queuePointer).to.equal(0) expect(exports.retryCount).to.equal(0) - const que = [[AUCTION_INIT, {type: AUCTION_INIT}]] + const que = [[AUCTION_INIT, { type: AUCTION_INIT }]] exports.__atmtdAnalyticsQueue.push(que[0]) exports.processEvents() expect(exports.prettyLog.getCall(0).args[0]).to.equal('status') @@ -451,7 +451,7 @@ describe('Automatad Analytics Adapter', () => { it('Should retry processing slotRenderEnded in certain intervals', () => { expect(exports.queuePointer).to.equal(0) expect(exports.retryCount).to.equal(0) - const que = [['slotRenderEnded', {type: 'slotRenderEnded'}]] + const que = [['slotRenderEnded', { type: 'slotRenderEnded' }]] exports.__atmtdAnalyticsQueue.push(que[0]) exports.processEvents() expect(exports.prettyLog.getCall(0).args[0]).to.equal('status') @@ -483,7 +483,7 @@ describe('Automatad Analytics Adapter', () => { it('Should retry processing impressionViewable in certain intervals', () => { expect(exports.queuePointer).to.equal(0) expect(exports.retryCount).to.equal(0) - const que = [['impressionViewable', {type: 'impressionViewable'}]] + const que = [['impressionViewable', { type: 'impressionViewable' }]] exports.__atmtdAnalyticsQueue.push(que[0]) exports.processEvents() expect(exports.prettyLog.getCall(0).args[0]).to.equal('status') @@ -545,17 +545,17 @@ describe('Automatad Analytics Adapter', () => { exports.retryCount = 0; exports.queuePointer = 0; exports.__atmtdAnalyticsQueue = [ - [AUCTION_INIT, {type: AUCTION_INIT}], - [BID_RESPONSE, {type: BID_RESPONSE}], - [BID_REQUESTED, {type: BID_REQUESTED}], - [BID_REJECTED, {type: BID_REJECTED}], - [NO_BID, {type: NO_BID}], - [BID_WON, {type: BID_WON}], - [BIDDER_DONE, {type: BIDDER_DONE}], - [AUCTION_DEBUG, {type: AUCTION_DEBUG}], - [BID_TIMEOUT, {type: BID_TIMEOUT}], - ['slotRenderEnded', {type: 'slotRenderEnded'}], - ['impressionViewable', {type: 'impressionViewable'}] + [AUCTION_INIT, { type: AUCTION_INIT }], + [BID_RESPONSE, { type: BID_RESPONSE }], + [BID_REQUESTED, { type: BID_REQUESTED }], + [BID_REJECTED, { type: BID_REJECTED }], + [NO_BID, { type: NO_BID }], + [BID_WON, { type: BID_WON }], + [BIDDER_DONE, { type: BIDDER_DONE }], + [AUCTION_DEBUG, { type: AUCTION_DEBUG }], + [BID_TIMEOUT, { type: BID_TIMEOUT }], + ['slotRenderEnded', { type: 'slotRenderEnded' }], + ['impressionViewable', { type: 'impressionViewable' }] ] }); afterEach(() => { diff --git a/test/spec/modules/automatadBidAdapter_spec.js b/test/spec/modules/automatadBidAdapter_spec.js index 050563d721b..d99df260431 100644 --- a/test/spec/modules/automatadBidAdapter_spec.js +++ b/test/spec/modules/automatadBidAdapter_spec.js @@ -7,7 +7,7 @@ describe('automatadBidAdapter', function () { const bidRequestRequiredParams = { bidder: 'automatad', - params: {siteId: '123ad'}, + params: { siteId: '123ad' }, mediaTypes: { banner: { sizes: [[300, 600]], @@ -25,7 +25,7 @@ describe('automatadBidAdapter', function () { const bidRequestAllParams = { bidder: 'automatad', - params: {siteId: '123ad', placementId: '123abc345'}, + params: { siteId: '123ad', placementId: '123abc345' }, mediaTypes: { banner: { sizes: [[300, 600]], @@ -93,7 +93,7 @@ describe('automatadBidAdapter', function () { }) describe('buildRequests', function () { - const req = spec.buildRequests([ bidRequestRequiredParams ], { refererInfo: { } }) + const req = spec.buildRequests([bidRequestRequiredParams], { refererInfo: { } }) let rdata it('should have withCredentials option as true', function() { @@ -178,12 +178,12 @@ describe('automatadBidAdapter', function () { } }] const result = spec.interpretResponse(multipleBidResponse[0]).map(bid => { - const {requestId} = bid; - return [ requestId ]; + const { requestId } = bid; + return [requestId]; }); assert.equal(result.length, 2); - assert.deepEqual(result, [[ 'imp1' ], [ 'imp2' ]]); + assert.deepEqual(result, [['imp1'], ['imp2']]); }) it('handles empty bid response', function () { diff --git a/test/spec/modules/azerionedgeRtdProvider_spec.js b/test/spec/modules/azerionedgeRtdProvider_spec.js index 82f4bb46c41..ef0da3f061b 100644 --- a/test/spec/modules/azerionedgeRtdProvider_spec.js +++ b/test/spec/modules/azerionedgeRtdProvider_spec.js @@ -13,7 +13,7 @@ describe('Azerion Edge RTD submodule', function () { const bidders = ['appnexus', 'improvedigital']; const process = { key: 'value' }; const dataProvider = { name: 'azerionedge', waitForIt: true }; - const userConsent = {gdpr: {gdprApplies: 'gdpr-applies', consentString: 'consent-string'}, usp: 'usp'}; + const userConsent = { gdpr: { gdprApplies: 'gdpr-applies', consentString: 'consent-string' }, usp: 'usp' }; const resetAll = () => { window.azerionPublisherAudiences.resetHistory(); @@ -65,7 +65,7 @@ describe('Azerion Edge RTD submodule', function () { ['uspConsent', userConsent.usp], ].forEach(([key, value]) => { it(`should call azerionPublisherAudiencesStub with ${key}:${value}`, function () { - expect(window.azerionPublisherAudiences.args[0][0]).to.include({[key]: value}); + expect(window.azerionPublisherAudiences.args[0][0]).to.include({ [key]: value }); }); }); @@ -104,7 +104,7 @@ describe('Azerion Edge RTD submodule', function () { ...Object.entries(process), ].forEach(([key, value]) => { it(`should call azerionPublisherAudiencesStub with ${key}:${value}`, function () { - expect(window.azerionPublisherAudiences.args[0][0]).to.include({[key]: value}); + expect(window.azerionPublisherAudiences.args[0][0]).to.include({ [key]: value }); }); }); }); diff --git a/test/spec/modules/beachfrontBidAdapter_spec.js b/test/spec/modules/beachfrontBidAdapter_spec.js index a881928a017..5425a84fffb 100644 --- a/test/spec/modules/beachfrontBidAdapter_spec.js +++ b/test/spec/modules/beachfrontBidAdapter_spec.js @@ -136,7 +136,7 @@ describe('BeachfrontAdapter', function () { it('should create a POST request for each bid', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(VIDEO_ENDPOINT + bidRequest.params.appId); }); @@ -148,7 +148,7 @@ describe('BeachfrontAdapter', function () { bidRequest.params.tagid = '7cd7a7b4-ef3f-4aeb-9565-3627f255fa10'; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] } }; const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true }); @@ -157,7 +157,7 @@ describe('BeachfrontAdapter', function () { page: topLocation.href } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.isPrebid).to.equal(true); expect(data.appId).to.equal(bidRequest.params.appId); @@ -175,7 +175,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; bidRequest.getFloor = () => ({ currency: 'USD', floor: 1.16 }); - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].bidfloor).to.equal(1.16); }); @@ -184,7 +184,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; bidRequest.getFloor = () => ({}); - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].bidfloor).to.equal(bidRequest.params.bidfloor); }); @@ -195,10 +195,10 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [[ width, height ]] + playerSize: [[width, height]] } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); }); @@ -212,7 +212,7 @@ describe('BeachfrontAdapter', function () { playerSize: `${width}x${height}` } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); }); @@ -224,7 +224,7 @@ describe('BeachfrontAdapter', function () { playerSize: [] } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ w: undefined, h: undefined }); }); @@ -233,9 +233,9 @@ describe('BeachfrontAdapter', function () { const width = 640; const height = 480; const bidRequest = bidRequests[0]; - bidRequest.sizes = [ width, height ]; + bidRequest.sizes = [width, height]; bidRequest.mediaTypes = { video: {} }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ w: width, h: height }); }); @@ -250,7 +250,7 @@ describe('BeachfrontAdapter', function () { bidRequest.mediaTypes = { video: { mimes, playbackmethod, maxduration, plcmt, skip } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ mimes, playbackmethod, maxduration, plcmt, skip }); }); @@ -264,7 +264,7 @@ describe('BeachfrontAdapter', function () { const skip = 1; bidRequest.mediaTypes = { video: { plcmt: 3, skip: 0 } }; bidRequest.params.video = { mimes, playbackmethod, maxduration, plcmt, skip }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.imp[0].video).to.deep.contain({ mimes, playbackmethod, maxduration, plcmt, skip }); }); @@ -274,7 +274,7 @@ describe('BeachfrontAdapter', function () { bidRequest.mediaTypes = { video: {} }; const uspConsent = '2112YYZ'; const bidderRequest = { uspConsent }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.regs.ext.us_privacy).to.equal(uspConsent); }); @@ -289,7 +289,7 @@ describe('BeachfrontAdapter', function () { consentString } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.regs.ext.gdpr).to.equal(1); expect(data.user.ext.consent).to.equal(consentString); @@ -306,7 +306,7 @@ describe('BeachfrontAdapter', function () { applicableSections } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.regs.gpp).to.equal(gppString); expect(data.regs.gpp_sid).to.deep.equal(applicableSections); @@ -328,7 +328,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; bidRequest.ortb2 = { source: { ext: { schain: schain } } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.source.ext.schain).to.deep.equal(schain); }); @@ -343,7 +343,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: {} }; bidRequest.userId = userId; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.user.ext.eids).to.deep.equal([ { @@ -408,7 +408,7 @@ describe('BeachfrontAdapter', function () { bidRequest.params.tagid = '7cd7a7b4-ef3f-4aeb-9565-3627f255fa10'; bidRequest.mediaTypes = { banner: { - sizes: [ width, height ] + sizes: [width, height] } }; const topLocation = parseUrl('http://www.example.com?foo=bar', { decodeSearchAsString: true }); @@ -417,7 +417,7 @@ describe('BeachfrontAdapter', function () { page: topLocation.href } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.slots).to.deep.equal([ { @@ -438,7 +438,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; bidRequest.getFloor = () => ({ currency: 'USD', floor: 1.16 }); - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].bidfloor).to.equal(1.16); }); @@ -447,7 +447,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; bidRequest.getFloor = () => ({}); - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].bidfloor).to.equal(bidRequest.params.bidfloor); }); @@ -458,10 +458,10 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: { - sizes: [[ width, height ]] + sizes: [[width, height]] } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].sizes).to.deep.equal([ { w: width, h: height } @@ -477,7 +477,7 @@ describe('BeachfrontAdapter', function () { sizes: `${width}x${height}` } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].sizes).to.deep.equal([ { w: width, h: height } @@ -491,7 +491,7 @@ describe('BeachfrontAdapter', function () { sizes: [] } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].sizes).to.deep.equal([]); }); @@ -500,9 +500,9 @@ describe('BeachfrontAdapter', function () { const width = 300; const height = 250; const bidRequest = bidRequests[0]; - bidRequest.sizes = [ width, height ]; + bidRequest.sizes = [width, height]; bidRequest.mediaTypes = { banner: {} }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.slots[0].sizes).to.deep.contain({ w: width, h: height }); }); @@ -512,7 +512,7 @@ describe('BeachfrontAdapter', function () { bidRequest.mediaTypes = { banner: {} }; const uspConsent = '2112YYZ'; const bidderRequest = { uspConsent }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.usPrivacy).to.equal(uspConsent); }); @@ -527,7 +527,7 @@ describe('BeachfrontAdapter', function () { consentString } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.gdpr).to.equal(1); expect(data.gdprConsent).to.equal(consentString); @@ -544,7 +544,7 @@ describe('BeachfrontAdapter', function () { applicableSections } }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.gpp).to.equal(gppString); expect(data.gppSid).to.deep.equal(applicableSections); @@ -566,7 +566,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; bidRequest.ortb2 = { source: { ext: { schain: schain } } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.schain).to.deep.equal(schain); }); @@ -581,7 +581,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; bidRequest.userId = userId; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); const data = requests[0].data; expect(data.tdid).to.equal(userId.tdid); expect(data.idl).to.equal(userId.idl_env); @@ -609,7 +609,7 @@ describe('BeachfrontAdapter', function () { }, ortb2 }; - const requests = spec.buildRequests([ bidRequest ], bidderRequest); + const requests = spec.buildRequests([bidRequest], bidderRequest); const data = requests[0].data; expect(data.user.data).to.equal('some user data'); expect(data.site.keywords).to.equal('test keyword'); @@ -628,7 +628,7 @@ describe('BeachfrontAdapter', function () { }; const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { banner: {} }; - const requests = spec.buildRequests([ bidRequest ], {ortb2}); + const requests = spec.buildRequests([bidRequest], { ortb2 }); const data = requests[0].data; expect(data.ortb2.user.data).to.equal('some user data'); expect(data.ortb2.site.keywords).to.equal('test keyword'); @@ -642,10 +642,10 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] }, banner: { - sizes: [ width, height ] + sizes: [width, height] } }; bidRequest.params = { @@ -658,7 +658,7 @@ describe('BeachfrontAdapter', function () { appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); expect(requests.length).to.equal(2); expect(requests[0].url).to.contain(VIDEO_ENDPOINT); expect(requests[1].url).to.contain(BANNER_ENDPOINT); @@ -668,10 +668,10 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ 640, 360 ] + playerSize: [640, 360] }, banner: { - sizes: [ 300, 250 ] + sizes: [300, 250] } }; bidRequest.params = { @@ -684,7 +684,7 @@ describe('BeachfrontAdapter', function () { appId: '3b16770b-17af-4d22-daff-9606bdf2c9c3' } }; - const requests = spec.buildRequests([ bidRequest ], {}); + const requests = spec.buildRequests([bidRequest], {}); expect(requests[0].data.imp[0].video).to.deep.contain({ w: 640, h: 360 }); expect(requests[1].data.slots[0].sizes).to.deep.equal([{ w: 300, h: 250 }]); }); @@ -716,7 +716,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] } }; const serverResponse = { @@ -749,7 +749,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] } }; bidRequest.params.video = { responseType: 'nurl' }; @@ -770,7 +770,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] } }; bidRequest.params.video = { responseType: 'adm' }; @@ -811,7 +811,7 @@ describe('BeachfrontAdapter', function () { const bidRequest = bidRequests[0]; bidRequest.mediaTypes = { video: { - playerSize: [ width, height ] + playerSize: [width, height] } }; const serverResponse = { @@ -849,12 +849,12 @@ describe('BeachfrontAdapter', function () { it('should return valid banner bid responses', function () { bidRequests[0].mediaTypes = { banner: { - sizes: [[ 300, 250 ], [ 728, 90 ]] + sizes: [[300, 250], [728, 90]] } }; bidRequests[1].mediaTypes = { banner: { - sizes: [[ 300, 600 ], [ 200, 200 ]] + sizes: [[300, 600], [200, 200]] } }; const serverResponse = [{ @@ -875,14 +875,14 @@ describe('BeachfrontAdapter', function () { const bidResponse = spec.interpretResponse({ body: serverResponse }, { bidRequest: bidRequests }); expect(bidResponse.length).to.equal(2); for (let i = 0; i < bidRequests.length; i++) { - expect(bidResponse[ i ]).to.deep.equal({ - requestId: bidRequests[ i ].bidId, + expect(bidResponse[i]).to.deep.equal({ + requestId: bidRequests[i].bidId, bidderCode: spec.code, - ad: serverResponse[ i ].adm, - creativeId: serverResponse[ i ].crid, - cpm: serverResponse[ i ].price, - width: serverResponse[ i ].w, - height: serverResponse[ i ].h, + ad: serverResponse[i].adm, + creativeId: serverResponse[i].crid, + cpm: serverResponse[i].price, + width: serverResponse[i].w, + height: serverResponse[i].h, meta: { mediaType: 'banner', advertiserDomains: [] }, mediaType: 'banner', currency: 'USD', @@ -895,7 +895,7 @@ describe('BeachfrontAdapter', function () { it('should return meta data for the bid response', () => { bidRequests[0].mediaTypes = { banner: { - sizes: [[ 300, 250 ], [ 728, 90 ]] + sizes: [[300, 250], [728, 90]] } }; const serverResponse = [{ diff --git a/test/spec/modules/beopBidAdapter_spec.js b/test/spec/modules/beopBidAdapter_spec.js index 08e14b76182..ae164b21b4c 100644 --- a/test/spec/modules/beopBidAdapter_spec.js +++ b/test/spec/modules/beopBidAdapter_spec.js @@ -288,7 +288,7 @@ describe('BeOp Bid Adapter tests', () => { spec.onBidWon({}); spec.onBidWon(); expect(triggerPixelStub.getCall(0)).to.be.null; - spec.onBidWon({params: {accountId: '5a8af500c9e77c00017e4cad'}, cpm: 1.2}); + spec.onBidWon({ params: { accountId: '5a8af500c9e77c00017e4cad' }, cpm: 1.2 }); expect(triggerPixelStub.getCall(0)).to.not.be.null; expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.include('https://t.collectiveaudience.co'); expect(triggerPixelStub.getCall(0).args[0]).to.include('se_ca=bid'); @@ -299,7 +299,7 @@ describe('BeOp Bid Adapter tests', () => { spec.onBidWon({}); spec.onBidWon(); expect(triggerPixelStub.getCall(0)).to.be.null; - spec.onBidWon({params: [{accountId: '5a8af500c9e77c00017e4cad'}], cpm: 1.2}); + spec.onBidWon({ params: [{ accountId: '5a8af500c9e77c00017e4cad' }], cpm: 1.2 }); expect(triggerPixelStub.getCall(0)).to.not.be.null; expect(triggerPixelStub.getCall(0).args[0]).to.exist.and.to.include('https://t.collectiveaudience.co'); expect(triggerPixelStub.getCall(0).args[0]).to.include('se_ca=bid'); @@ -368,7 +368,7 @@ describe('BeOp Bid Adapter tests', () => { it(`should get eids from bid`, function () { const bid = Object.assign({}, validBid); - bid.userIdAsEids = [{source: 'provider.com', uids: [{id: 'someid', atype: 1, ext: {whatever: true}}]}]; + bid.userIdAsEids = [{ source: 'provider.com', uids: [{ id: 'someid', atype: 1, ext: { whatever: true } }] }]; bidRequests.push(bid); const request = spec.buildRequests(bidRequests, {}); @@ -389,6 +389,107 @@ describe('BeOp Bid Adapter tests', () => { expect(payload.fg).to.exist; }) }) + describe('slot name normalization', function () { + it('should preserve non-GPT adUnitCode unchanged (case-sensitive)', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = '/Network/TopBanner'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('/Network/TopBanner'); + }); + + it('should preserve mixed-case custom adUnitCode unchanged', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'InArticleSlot'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('InArticleSlot'); + }); + + it('should normalize GPT auto-generated adUnitCode by removing prefix', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-article_top'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('article_top'); + }); + + it('should remove long numeric suffix from GPT adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-sidebar_123456'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('sidebar'); + }); + + it('should remove timestamp-like suffix from GPT adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-header-1678459238475'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('header'); + }); + + it('should preserve short numeric suffix in GPT adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-topbanner-1'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('topbanner-1'); + }); + + it('should preserve short numeric suffix like -2 in GPT adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-article_slot-2'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('article_slot-2'); + }); + + it('should handle GPT adUnitCode with underscore separator', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad_content_main'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('content_main'); + }); + + it('should return undefined for too short GPT slot names', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-ab'; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.be.undefined; + }); + + it('should prefer gpid over adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-fallback'; + bid.ortb2Imp = { ext: { gpid: '/123/preferred-slot' } }; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('/123/preferred-slot'); + }); + + it('should prefer adslot over adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-fallback'; + bid.ortb2Imp = { ext: { data: { adslot: '/456/adslot-name' } } }; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('/456/adslot-name'); + }); + + it('should prefer tagid over normalized adUnitCode', function () { + const bid = Object.assign({}, validBid); + bid.adUnitCode = 'div-gpt-ad-fallback'; + bid.ortb2Imp = { tagid: 'custom-tagid' }; + const request = spec.buildRequests([bid], {}); + const payload = JSON.parse(request.data); + expect(payload.slts[0].name).to.equal('custom-tagid'); + }); + }); + describe('getUserSyncs', function () { it('should return iframe sync when iframeEnabled and syncFrame provided', function () { const syncOptions = { iframeEnabled: true, pixelEnabled: false }; diff --git a/test/spec/modules/betweenBidAdapter_spec.js b/test/spec/modules/betweenBidAdapter_spec.js index 857779ca355..da76286ae22 100644 --- a/test/spec/modules/betweenBidAdapter_spec.js +++ b/test/spec/modules/betweenBidAdapter_spec.js @@ -16,7 +16,7 @@ describe('betweenBidAdapterTests', function () { const bidRequestData = [{ bidId: 'bid1234', bidder: 'between', - params: {w: 240, h: 400, s: 1112}, + params: { w: 240, h: 400, s: 1112 }, sizes: [[240, 400]] }] const request = spec.buildRequests(bidRequestData); @@ -28,7 +28,7 @@ describe('betweenBidAdapterTests', function () { const bidRequestData = [{ bidId: 'bid1234', bidder: 'between', - params: {w: 240, h: 400, s: 1112}, + params: { w: 240, h: 400, s: 1112 }, mediaTypes: { video: { context: 'outstream', @@ -305,8 +305,8 @@ describe('betweenBidAdapterTests', function () { it('check getUserSyncs', function() { const syncs = spec.getUserSyncs({}, {}); expect(syncs).to.be.an('array').that.to.have.lengthOf(2); - expect(syncs[0]).to.deep.equal({type: 'iframe', url: 'https://ads.betweendigital.com/sspmatch-iframe'}); - expect(syncs[1]).to.deep.equal({type: 'image', url: 'https://ads.betweendigital.com/sspmatch'}); + expect(syncs[0]).to.deep.equal({ type: 'iframe', url: 'https://ads.betweendigital.com/sspmatch-iframe' }); + expect(syncs[1]).to.deep.equal({ type: 'image', url: 'https://ads.betweendigital.com/sspmatch' }); }); it('check sizes', function() { diff --git a/test/spec/modules/beyondmediaBidAdapter_spec.js b/test/spec/modules/beyondmediaBidAdapter_spec.js index 79bf88cb6be..5ee8d73207b 100644 --- a/test/spec/modules/beyondmediaBidAdapter_spec.js +++ b/test/spec/modules/beyondmediaBidAdapter_spec.js @@ -431,7 +431,7 @@ describe('AndBeyondMediaBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -440,9 +440,7 @@ describe('AndBeyondMediaBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookies.andbeyond.media/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -451,7 +449,7 @@ describe('AndBeyondMediaBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookies.andbeyond.media/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/bidResponseFilter_spec.js b/test/spec/modules/bidResponseFilter_spec.js index c37003bde50..c7e6433a112 100644 --- a/test/spec/modules/bidResponseFilter_spec.js +++ b/test/spec/modules/bidResponseFilter_spec.js @@ -35,7 +35,7 @@ describe('bidResponseFilter', () => { it('should not run if not configured', () => { reset(); - addBidResponse.call({dispatch}, 'au', {}, reject); + addBidResponse.call({ dispatch }, 'au', {}, reject); sinon.assert.notCalled(reject); sinon.assert.called(dispatch); }); @@ -44,7 +44,7 @@ describe('bidResponseFilter', () => { config.setConfig({ bidResponseFilter: {} }); - addBidResponse.call({dispatch}, 'au', {}, reject); + addBidResponse.call({ dispatch }, 'au', {}, reject); sinon.assert.called(reject); sinon.assert.notCalled(dispatch); }) @@ -69,7 +69,8 @@ describe('bidResponseFilter', () => { advertiserDomains: ['domain1.com', 'domain2.com'], primaryCatId: 'EXAMPLE-CAT-ID', attr: 'attr', - mediaType: 'banner' + mediaType: 'banner', + cattax: 1 } }; @@ -85,7 +86,8 @@ describe('bidResponseFilter', () => { meta: { advertiserDomains: ['domain1.com', 'domain2.com'], primaryCatId: 'BANNED_CAT1', - attr: 'attr' + attr: 'attr', + cattax: 1 } }; mockAuctionIndex.getOrtb2 = () => ({ @@ -96,6 +98,109 @@ describe('bidResponseFilter', () => { sinon.assert.calledWith(reject, BID_CATEGORY_REJECTION_REASON); }); + describe('cattax (category taxonomy) match', () => { + it('should reject with BID_CATEGORY_REJECTION_REASON when cattax matches and primaryCatId is in bcat blocklist', () => { + const reject = sinon.stub(); + const call = sinon.stub(); + const bid = { + meta: { + advertiserDomains: ['domain1.com'], + primaryCatId: 'BANNED_CAT1', + attr: 1, + mediaType: 'banner', + cattax: 1 + } + }; + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1'], cattax: 1 + }); + mockAuctionIndex.getBidRequest = () => ({ + mediaTypes: { banner: {} }, + ortb2Imp: {} + }); + + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); + sinon.assert.calledWith(reject, BID_CATEGORY_REJECTION_REASON); + sinon.assert.notCalled(call); + }); + + it('should pass when cattax matches and primaryCatId is not in bcat blocklist', () => { + const reject = sinon.stub(); + const call = sinon.stub(); + const bid = { + meta: { + advertiserDomains: ['domain1.com'], + primaryCatId: 'ALLOWED_CAT', + attr: 1, + mediaType: 'banner', + cattax: 1 + } + }; + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1'], cattax: 1 + }); + mockAuctionIndex.getBidRequest = () => ({ + mediaTypes: { banner: {} }, + ortb2Imp: {} + }); + + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); + sinon.assert.notCalled(reject); + sinon.assert.calledOnce(call); + }); + + it('should reject with BID_CATEGORY_REJECTION_REASON when cattax does not match (treat primaryCatId as unknown)', () => { + const reject = sinon.stub(); + const call = sinon.stub(); + const bid = { + meta: { + advertiserDomains: ['domain1.com'], + primaryCatId: 'ALLOWED_CAT', + attr: 1, + mediaType: 'banner', + cattax: 2 + } + }; + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1'], cattax: 1 + }); + mockAuctionIndex.getBidRequest = () => ({ + mediaTypes: { banner: {} }, + ortb2Imp: {} + }); + + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); + sinon.assert.calledWith(reject, BID_CATEGORY_REJECTION_REASON); + sinon.assert.notCalled(call); + }); + + it('should pass when cattax does not match and blockUnknown is false (do not treat as unknown)', () => { + const reject = sinon.stub(); + const call = sinon.stub(); + const bid = { + meta: { + advertiserDomains: ['domain1.com'], + primaryCatId: 'BANNED_CAT1', + attr: 1, + mediaType: 'banner', + cattax: 2 + } + }; + mockAuctionIndex.getOrtb2 = () => ({ + badv: [], bcat: ['BANNED_CAT1'], cattax: 1 + }); + mockAuctionIndex.getBidRequest = () => ({ + mediaTypes: { banner: {} }, + ortb2Imp: {} + }); + config.setConfig({ [MODULE_NAME]: { cat: { blockUnknown: false } } }); + + addBidResponseHook(call, 'adcode', bid, reject, mockAuctionIndex); + sinon.assert.notCalled(reject); + sinon.assert.calledOnce(call); + }); + }); + it('should reject the bid after failed ortb2 adv domains rule validation', () => { const rejection = sinon.stub(); const call = sinon.stub(); @@ -103,7 +208,8 @@ describe('bidResponseFilter', () => { meta: { advertiserDomains: ['domain1.com', 'domain2.com'], primaryCatId: 'VALID_CAT', - attr: 'attr' + attr: 'attr', + cattax: 1 } }; mockAuctionIndex.getOrtb2 = () => ({ @@ -121,7 +227,8 @@ describe('bidResponseFilter', () => { meta: { advertiserDomains: ['validdomain1.com', 'validdomain2.com'], primaryCatId: 'VALID_CAT', - attr: 'BANNED_ATTR' + attr: 'BANNED_ATTR', + cattax: 1 }, mediaType: 'video' }; @@ -149,6 +256,7 @@ describe('bidResponseFilter', () => { primaryCatId: 'BANNED_CAT1', attr: 'valid_attr', mediaType: 'banner', + cattax: 1 } }; @@ -163,7 +271,7 @@ describe('bidResponseFilter', () => { badv: ['domain2.com'], bcat: ['BANNED_CAT1', 'BANNED_CAT2'] }); - config.setConfig({[MODULE_NAME]: {cat: {enforce: false}}}); + config.setConfig({ [MODULE_NAME]: { cat: { enforce: false } } }); addBidResponseHook(call, 'adcode', bid, () => { }, mockAuctionIndex); @@ -177,7 +285,8 @@ describe('bidResponseFilter', () => { advertiserDomains: ['validdomain1.com', 'validdomain2.com'], primaryCatId: undefined, attr: 'valid_attr', - mediaType: 'banner' + mediaType: 'banner', + cattax: 1 } }; @@ -192,7 +301,7 @@ describe('bidResponseFilter', () => { ortb2Imp: {} }) - config.setConfig({[MODULE_NAME]: {cat: {blockUnknown: false}}}); + config.setConfig({ [MODULE_NAME]: { cat: { blockUnknown: false } } }); addBidResponseHook(call, 'adcode', bid, () => { }, mockAuctionIndex); @@ -207,7 +316,8 @@ describe('bidResponseFilter', () => { advertiserDomains: ['validdomain1.com', 'validdomain2.com'], primaryCatId: 'VALID_CAT', attr: 6, - mediaType: 'audio' + mediaType: 'audio', + cattax: 1 }, }; diff --git a/test/spec/modules/bidViewability_spec.js b/test/spec/modules/bidViewability_spec.js index e33e4a9687b..3c64d1e6781 100644 --- a/test/spec/modules/bidViewability_spec.js +++ b/test/spec/modules/bidViewability_spec.js @@ -3,7 +3,7 @@ import { config } from 'src/config.js'; import * as events from 'src/events.js'; import * as utils from 'src/utils.js'; import * as sinon from 'sinon'; -import {expect, spy} from 'chai'; +import { expect, spy } from 'chai'; import * as prebidGlobal from 'src/prebidGlobal.js'; import { EVENTS } from 'src/constants.js'; import adapterManager, { gdprDataHandler, uspDataHandler } from 'src/adapterManager.js'; @@ -96,7 +96,7 @@ describe('#bidViewability', function() { return ('AD-' + slot.getAdUnitPath()) === bid.adUnitCode; } }; - const newWinningBid = Object.assign({}, PBJS_WINNING_BID, {adUnitCode: 'AD-' + PBJS_WINNING_BID.adUnitCode}); + const newWinningBid = Object.assign({}, PBJS_WINNING_BID, { adUnitCode: 'AD-' + PBJS_WINNING_BID.adUnitCode }); // Needs pbjs.getWinningBids to be implemented with match winningBidsArray.push(newWinningBid); const wb = bidViewability.getMatchingWinningBidForGPTSlot(bidViewabilityConfig, gptSlot); @@ -151,7 +151,7 @@ describe('#bidViewability', function() { }); it('fire pixels if mentioned in module config', function() { - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); @@ -162,7 +162,7 @@ describe('#bidViewability', function() { it('USP: should include the us_privacy key when USP Consent is available', function () { const uspDataHandlerStub = sinon.stub(uspDataHandler, 'getConsentData'); uspDataHandlerStub.returns('1YYY'); - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); @@ -175,7 +175,7 @@ describe('#bidViewability', function() { }); it('USP: should not include the us_privacy key when USP Consent is not available', function () { - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); @@ -193,7 +193,7 @@ describe('#bidViewability', function() { consentString: 'consent', addtlConsent: 'moreConsent' }); - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); @@ -208,7 +208,7 @@ describe('#bidViewability', function() { }); it('GDPR: should not include the GDPR keys when GDPR Consent is not available', function () { - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); @@ -227,7 +227,7 @@ describe('#bidViewability', function() { gdprApplies: true, consentString: 'consent' }); - const moduleConfig = {firePixels: true}; + const moduleConfig = { firePixels: true }; bidViewability.fireViewabilityPixels(moduleConfig, PBJS_WINNING_BID); PBJS_WINNING_BID.vurls.forEach((url, i) => { const call = triggerPixelSpy.getCall(i); diff --git a/test/spec/modules/biddoBidAdapter_spec.js b/test/spec/modules/biddoBidAdapter_spec.js index 25986b3407f..99affeb3815 100644 --- a/test/spec/modules/biddoBidAdapter_spec.js +++ b/test/spec/modules/biddoBidAdapter_spec.js @@ -1,12 +1,12 @@ -import {expect} from 'chai'; -import {spec} from 'modules/biddoBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/biddoBidAdapter.js'; describe('biddo bid adapter tests', function () { describe('bid requests', function () { it('should accept valid bid', function () { const validBid = { bidder: 'biddo', - params: {zoneId: 123}, + params: { zoneId: 123 }, }; expect(spec.isBidRequestValid(validBid)).to.equal(true); @@ -24,7 +24,7 @@ describe('biddo bid adapter tests', function () { it('should correctly build payload string', function () { const bidRequests = [{ bidder: 'biddo', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250]], @@ -46,7 +46,7 @@ describe('biddo bid adapter tests', function () { it('should support multiple bids', function () { const bidRequests = [{ bidder: 'biddo', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250]], @@ -58,7 +58,7 @@ describe('biddo bid adapter tests', function () { transactionId: '92489f71-1bf2-49a0-adf9-000cea934729', }, { bidder: 'biddo', - params: {zoneId: 321}, + params: { zoneId: 321 }, mediaTypes: { banner: { sizes: [[728, 90]], @@ -77,7 +77,7 @@ describe('biddo bid adapter tests', function () { it('should support multiple sizes', function () { const bidRequests = [{ bidder: 'biddo', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250], [300, 600]], @@ -118,7 +118,7 @@ describe('biddo bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(1); expect(bids[0].requestId).to.equal('23acc48ad47af5'); @@ -144,7 +144,7 @@ describe('biddo bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(0); }); @@ -164,7 +164,7 @@ describe('biddo bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(0); }); diff --git a/test/spec/modules/bidfuseBidAdapter_spec.js b/test/spec/modules/bidfuseBidAdapter_spec.js index 95c84dcdf87..419cf6e6f3e 100644 --- a/test/spec/modules/bidfuseBidAdapter_spec.js +++ b/test/spec/modules/bidfuseBidAdapter_spec.js @@ -287,7 +287,7 @@ describe('BidfuseBidAdapter', function () { describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + const result = spec.getUserSyncs({ iframeEnabled: true }, [serverResponse]); expect(result).to.deep.equal([{ type: 'iframe', @@ -296,7 +296,7 @@ describe('BidfuseBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + const result = spec.getUserSyncs({ iframeEnabled: true }, [serverResponse]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://syncbf.bidfuse.com/iframe?pbjs=1&coppa=0' @@ -304,7 +304,7 @@ describe('BidfuseBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = spec.getUserSyncs({pixelEnabled: true}, [serverResponse]); + const result = spec.getUserSyncs({ pixelEnabled: true }, [serverResponse]); expect(result).to.deep.equal([{ 'url': 'https://syncbf.bidfuse.com/image?pbjs=1&coppa=0', @@ -316,7 +316,7 @@ describe('BidfuseBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + const result = spec.getUserSyncs({ iframeEnabled: true }, [serverResponse]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://syncbf.bidfuse.com/iframe?pbjs=1&coppa=1' @@ -334,10 +334,10 @@ describe('BidfuseBidAdapter', function () { applicableSections: [7] } - const result = spec.getUserSyncs({pixelEnabled: true}, [serverResponse], gdprConsent, uspConsent, gppConsent); + const result = spec.getUserSyncs({ pixelEnabled: true }, [serverResponse], gdprConsent, uspConsent, gppConsent); expect(result).to.deep.equal([{ - 'url': 'https://syncbf.bidfuse.com/image?pbjs=1&gdpr=1&gdpr_consent=consent_string&gpp=gpp_string&gpp_sid=7&coppa=1', + 'url': 'https://syncbf.bidfuse.com/image?pbjs=1&gdpr=1&gdpr_consent=consent_string&ccpa_consent=usp_string&gpp=gpp_string&gpp_sid=7&coppa=1', 'type': 'image' }]); }); diff --git a/test/spec/modules/bidmaticBidAdapter_spec.js b/test/spec/modules/bidmaticBidAdapter_spec.js index dfce07648f7..bf02d6e3ab1 100644 --- a/test/spec/modules/bidmaticBidAdapter_spec.js +++ b/test/spec/modules/bidmaticBidAdapter_spec.js @@ -386,9 +386,11 @@ describe('bidmaticBidAdapter', function () { const syncOptions = { pixelEnabled: true, iframeEnabled: true }; const serverResponses = [ { body: { cookieURLs: ['https://sync1.bidmatic.com/pixel'] } }, - { body: [ - { cookieURLs: ['https://sync2.bidmatic.com/iframe'], cookieURLSTypes: ['iframe'] } - ]} + { + body: [ + { cookieURLs: ['https://sync2.bidmatic.com/iframe'], cookieURLSTypes: ['iframe'] } + ] + } ]; const result = getUserSyncsFn(syncOptions, serverResponses); diff --git a/test/spec/modules/bidtheatreBidAdapter_spec.js b/test/spec/modules/bidtheatreBidAdapter_spec.js index 351f59680b5..74cff812db4 100644 --- a/test/spec/modules/bidtheatreBidAdapter_spec.js +++ b/test/spec/modules/bidtheatreBidAdapter_spec.js @@ -34,7 +34,7 @@ const BANNER_BID_REQUEST = [ } ]; -const BANNER_BIDDER_REQUEST = {'bidderCode': BIDDER_CODE, 'bids': BANNER_BID_REQUEST}; +const BANNER_BIDDER_REQUEST = { 'bidderCode': BIDDER_CODE, 'bids': BANNER_BID_REQUEST }; const BANNER_BID_RESPONSE = { 'cur': 'USD', @@ -92,7 +92,7 @@ const VIDEO_BID_REQUEST = [ } ]; -const VIDEO_BIDDER_REQUEST = {'bidderCode': BIDDER_CODE, 'bids': VIDEO_BID_REQUEST}; +const VIDEO_BIDDER_REQUEST = { 'bidderCode': BIDDER_CODE, 'bids': VIDEO_BID_REQUEST }; const VIDEO_BID_RESPONSE = { 'cur': 'USD', @@ -195,20 +195,20 @@ describe('BidtheatreAdapter', function () { describe('interpretResponse', function () { it('should have exactly one bid in banner response', function () { const request = spec.buildRequests(BANNER_BID_REQUEST, BANNER_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: BANNER_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: BANNER_BID_RESPONSE }, request[0]); expect(bids).to.be.an('array').with.lengthOf(1); expect(bids[0]).to.be.an('object'); }); it('should have currency set to USD in banner response', function () { const request = spec.buildRequests(BANNER_BID_REQUEST, BANNER_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: BANNER_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: BANNER_BID_RESPONSE }, request[0]); expect(bids[0].currency).to.be.a('string').and.to.equal(DEFAULT_CURRENCY); }); it('should have ad in response and auction price macros replaced in banner response', function () { const request = spec.buildRequests(BANNER_BID_REQUEST, BANNER_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: BANNER_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: BANNER_BID_RESPONSE }, request[0]); const ad = bids[0].ad; expect(ad).to.exist; expect(ad).to.be.a('string'); @@ -219,20 +219,20 @@ describe('BidtheatreAdapter', function () { if (FEATURES.VIDEO) { it('should have exactly one bid in video response', function () { const request = spec.buildRequests(VIDEO_BID_REQUEST, VIDEO_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: VIDEO_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: VIDEO_BID_RESPONSE }, request[0]); expect(bids).to.be.an('array').with.lengthOf(1); expect(bids[0]).to.be.an('object'); }); it('should have currency set to USD in video response', function () { const request = spec.buildRequests(VIDEO_BID_REQUEST, VIDEO_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: VIDEO_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: VIDEO_BID_RESPONSE }, request[0]); expect(bids[0].currency).to.be.a('string').and.to.equal(DEFAULT_CURRENCY); }); it('should have vastUrl in response and auction price macros replaced in video response', function () { const request = spec.buildRequests(VIDEO_BID_REQUEST, VIDEO_BIDDER_REQUEST); - const bids = spec.interpretResponse({body: VIDEO_BID_RESPONSE}, request[0]); + const bids = spec.interpretResponse({ body: VIDEO_BID_RESPONSE }, request[0]); const vastUrl = bids[0].vastUrl; expect(vastUrl).to.exist; expect(vastUrl).to.be.a('string'); @@ -260,7 +260,7 @@ describe('BidtheatreAdapter', function () { }); it('should return usersync url when pixel is allowed and present in bid response', function () { - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: bidResponse}], gdprConsent)).to.deep.equal([{ type: 'image', url: bidResponseSyncURL }]); + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: bidResponse }], gdprConsent)).to.deep.equal([{ type: 'image', url: bidResponseSyncURL }]); }); }); }); diff --git a/test/spec/modules/big-richmediaBidAdapter_spec.js b/test/spec/modules/big-richmediaBidAdapter_spec.js index ffddad0003d..5ed446f2720 100644 --- a/test/spec/modules/big-richmediaBidAdapter_spec.js +++ b/test/spec/modules/big-richmediaBidAdapter_spec.js @@ -215,7 +215,7 @@ describe('bigRichMediaAdapterTests', function () { adUnitCode: 'code' }] }; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); @@ -249,7 +249,7 @@ describe('bigRichMediaAdapterTests', function () { }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).not.to.have.property('vastXml'); expect(result[0]).not.to.have.property('vastUrl'); expect(result[0]).to.have.property('width', 1); diff --git a/test/spec/modules/bitmediaBidAdapter_spec.js b/test/spec/modules/bitmediaBidAdapter_spec.js index 537ae38354b..7f55a53307c 100644 --- a/test/spec/modules/bitmediaBidAdapter_spec.js +++ b/test/spec/modules/bitmediaBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec, STORAGE, ENDPOINT_URL} from 'modules/bitmediaBidAdapter.js'; +import { expect } from 'chai'; +import { spec, STORAGE, ENDPOINT_URL } from 'modules/bitmediaBidAdapter.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; -import {BANNER} from '../../../src/mediaTypes.js'; +import { config } from 'src/config.js'; +import { BANNER } from '../../../src/mediaTypes.js'; describe('Bitmedia Bid Adapter', function () { const createBidRequest = (sandbox, overrides = {}) => { @@ -331,11 +331,11 @@ describe('Bitmedia Bid Adapter', function () { beforeEach(function () { const getFloorStub = sinon.stub(); - getFloorStub.withArgs({currency: 'USD', mediaType: 'banner', size: [300, 250]}).returns({ + getFloorStub.withArgs({ currency: 'USD', mediaType: 'banner', size: [300, 250] }).returns({ currency: 'USD', floor: 0.5 }); - getFloorStub.withArgs({currency: 'USD', mediaType: 'banner', size: [300, 600]}).returns({ + getFloorStub.withArgs({ currency: 'USD', mediaType: 'banner', size: [300, 600] }).returns({ currency: 'USD', floor: 0.7 }); @@ -351,9 +351,9 @@ describe('Bitmedia Bid Adapter', function () { it('should include the correct bidfloor per impression', function () { expect(imp[0].bidfloor).to.equal(0.5); - expect(imp[0].banner).to.deep.equal({w: 300, h: 250}); + expect(imp[0].banner).to.deep.equal({ w: 300, h: 250 }); expect(imp[1].bidfloor).to.equal(0.7); - expect(imp[1].banner).to.deep.equal({w: 300, h: 600}); + expect(imp[1].banner).to.deep.equal({ w: 300, h: 600 }); }); }); @@ -456,7 +456,7 @@ describe('Bitmedia Bid Adapter', function () { }); it('should return an empty array when server response is empty', function () { - const serverResponse = {body: {}}; + const serverResponse = { body: {} }; const bidRequest = {}; const bids = spec.interpretResponse(serverResponse, bidRequest); diff --git a/test/spec/modules/blastoBidAdapter_spec.js b/test/spec/modules/blastoBidAdapter_spec.js index d0cd8e22b5e..9265ebd0cd0 100644 --- a/test/spec/modules/blastoBidAdapter_spec.js +++ b/test/spec/modules/blastoBidAdapter_spec.js @@ -185,7 +185,7 @@ describe('blastoAdapter', function () { }); it('should send the CCPA data in the request', async function () { - const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({...bidderRequest, ...{uspConsent: '1YYY'}})); + const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({ ...bidderRequest, ...{ uspConsent: '1YYY' } })); expect(serverRequest.data.regs.ext.us_privacy).to.equal('1YYY'); }); }); diff --git a/test/spec/modules/bliinkBidAdapter_spec.js b/test/spec/modules/bliinkBidAdapter_spec.js index 885a50e0caa..61926b7d570 100644 --- a/test/spec/modules/bliinkBidAdapter_spec.js +++ b/test/spec/modules/bliinkBidAdapter_spec.js @@ -355,17 +355,19 @@ const GetUserIds = [ { title: 'Should return eids if exists', args: { - fn: getUserIds([{ userIdAsEids: [ - { - 'source': 'criteo.com', - 'uids': [ - { - 'id': 'testId', - 'atype': 1 - } - ] - } - ] }]), + fn: getUserIds([{ + userIdAsEids: [ + { + 'source': 'criteo.com', + 'uids': [ + { + 'id': 'testId', + 'atype': 1 + } + ] + } + ] + }]), }, want: [ { diff --git a/test/spec/modules/blueconicRtdProvider_spec.js b/test/spec/modules/blueconicRtdProvider_spec.js index 4fe85d8a9c8..37bf82fbf91 100644 --- a/test/spec/modules/blueconicRtdProvider_spec.js +++ b/test/spec/modules/blueconicRtdProvider_spec.js @@ -1,5 +1,5 @@ -import {config} from 'src/config.js'; -import {RTD_LOCAL_NAME, addRealTimeData, getRealTimeData, blueconicSubmodule, storage} from 'modules/blueconicRtdProvider.js'; +import { config } from 'src/config.js'; +import { RTD_LOCAL_NAME, addRealTimeData, getRealTimeData, blueconicSubmodule, storage } from 'modules/blueconicRtdProvider.js'; describe('blueconicRtdProvider', function() { let getDataFromLocalStorageStub; @@ -22,13 +22,13 @@ describe('blueconicRtdProvider', function() { it('merges ortb2Fragment data', function() { const setConfigUserObj1 = { name: 'www.dataprovider1.com', - ext: {segtax: 1}, - segment: [{id: '1776'}] + ext: { segtax: 1 }, + segment: [{ id: '1776' }] }; const setConfigUserObj2 = { name: 'www.dataprovider2.com', - ext: {segtax: 1}, - segment: [{id: '1914'} + ext: { segtax: 1 }, + segment: [{ id: '1914' } ] }; @@ -44,8 +44,8 @@ describe('blueconicRtdProvider', function() { const rtdUserObj1 = { name: 'www.dataprovider4.com', - ext: {segtax: 1}, - segment: [{id: '1918'}, {id: '1939'} + ext: { segtax: 1 }, + segment: [{ id: '1918' }, { id: '1939' } ] }; @@ -66,16 +66,15 @@ describe('blueconicRtdProvider', function() { it('merges data without duplication', function() { const userObj1 = { name: 'www.dataprovider1.com', - ext: {segtax: 1}, - segment: [{id: '1776'} + ext: { segtax: 1 }, + segment: [{ id: '1776' } ] }; const userObj2 = { - ext: {segtax: 1}, + ext: { segtax: 1 }, name: 'www.dataprovider2.com', - segment: [{id: '1914' - }] + segment: [{ id: '1914' }] }; const bidConfig = { @@ -113,19 +112,20 @@ describe('blueconicRtdProvider', function() { requestParams: { publisherId: 'Publisher1', coppa: true - }} + } + } }; - const bidConfig = {ortb2Fragments: {global: {}}}; + const bidConfig = { ortb2Fragments: { global: {} } }; const rtdUserObj1 = { name: 'blueconic', - ext: {segtax: 1}, - segment: [{id: 'bf23d802-931d-4619-8266-ce9a6328aa2a'}], + ext: { segtax: 1 }, + segment: [{ id: 'bf23d802-931d-4619-8266-ce9a6328aa2a' }], bidId: '1234' }; - const cachedRtd = {ext: {segtax: 1}, 'segment': [{id: 'bf23d802-931d-4619-8266-ce9a6328aa2a'}], 'bidId': '1234'} + const cachedRtd = { ext: { segtax: 1 }, 'segment': [{ id: 'bf23d802-931d-4619-8266-ce9a6328aa2a' }], 'bidId': '1234' } getDataFromLocalStorageStub.withArgs(RTD_LOCAL_NAME).returns(JSON.stringify(cachedRtd)); getRealTimeData(bidConfig, () => {}, rtdConfig, {}); diff --git a/test/spec/modules/boldwinBidAdapter_spec.js b/test/spec/modules/boldwinBidAdapter_spec.js index 5d8c7fab9fd..fdaa0f19f3f 100644 --- a/test/spec/modules/boldwinBidAdapter_spec.js +++ b/test/spec/modules/boldwinBidAdapter_spec.js @@ -434,7 +434,7 @@ describe('BoldwinBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -443,9 +443,7 @@ describe('BoldwinBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.videowalldirect.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -454,7 +452,7 @@ describe('BoldwinBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.videowalldirect.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/brandmetricsRtdProvider_spec.js b/test/spec/modules/brandmetricsRtdProvider_spec.js index 6bc521b21c1..6e21023e9e8 100644 --- a/test/spec/modules/brandmetricsRtdProvider_spec.js +++ b/test/spec/modules/brandmetricsRtdProvider_spec.js @@ -1,5 +1,5 @@ import * as brandmetricsRTD from '../../../modules/brandmetricsRtdProvider.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import * as events from '../../../src/events.js'; import * as sinon from 'sinon'; @@ -135,7 +135,7 @@ describe('getBidRequestData', () => { it('should set targeting keys for specified bidders', () => { const bidderOrtb2 = {}; - brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ortb2Fragments: {bidder: bidderOrtb2}}, () => { + brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ ortb2Fragments: { bidder: bidderOrtb2 } }, () => { const expected = VALID_CONFIG.params.bidders expected.forEach(exp => { @@ -172,7 +172,7 @@ describe('getBidRequestData', () => { }); const bidderOrtb2 = {}; - brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ortb2Fragments: {bidder: bidderOrtb2}}, () => {}, VALID_CONFIG); + brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ ortb2Fragments: { bidder: bidderOrtb2 } }, () => {}, VALID_CONFIG); expect(Object.keys(bidderOrtb2).length).to.equal(0) }); @@ -190,7 +190,7 @@ describe('getBidRequestData', () => { }); const bidderOrtb2 = {}; - brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ortb2Fragments: {bidder: bidderOrtb2}}, () => {}, VALID_CONFIG); + brandmetricsRTD.brandmetricsSubmodule.getBidRequestData({ ortb2Fragments: { bidder: bidderOrtb2 } }, () => {}, VALID_CONFIG); const expected = VALID_CONFIG.params.bidders diff --git a/test/spec/modules/braveBidAdapter_spec.js b/test/spec/modules/braveBidAdapter_spec.js index 92a235a92ea..1d6366f72b7 100644 --- a/test/spec/modules/braveBidAdapter_spec.js +++ b/test/spec/modules/braveBidAdapter_spec.js @@ -65,25 +65,26 @@ const bidRequest = { const request_video = { code: 'brave-video-prebid', - mediaTypes: { video: { - minduration: 1, - maxduration: 999, - boxingallowed: 1, - skip: 0, - mimes: [ - 'application/javascript', - 'video/mp4' - ], - playerSize: [[768, 1024]], - protocols: [ - 2, 3 - ], - linearity: 1, - api: [ - 1, - 2 - ] - } + mediaTypes: { + video: { + minduration: 1, + maxduration: 999, + boxingallowed: 1, + skip: 0, + mimes: [ + 'application/javascript', + 'video/mp4' + ], + playerSize: [[768, 1024]], + protocols: [ + 2, 3 + ], + linearity: 1, + api: [ + 1, + 2 + ] + } }, bidder: 'brave', @@ -144,17 +145,18 @@ const response_native = { impid: 'request_imp_id', price: 5, adomain: ['example.com'], - adm: { native: + adm: { + native: { assets: [ - {id: 1, title: 'dummyText'}, - {id: 3, image: imgData}, + { id: 1, title: 'dummyText' }, + { id: 3, image: imgData }, { id: 5, - data: {value: 'organization.name'} + data: { value: 'organization.name' } } ], - link: {url: 'example.com'}, + link: { url: 'example.com' }, imptrackers: ['tracker1.com', 'tracker2.com', 'tracker3.com'], jstracker: 'tracker1.com' } @@ -340,7 +342,7 @@ describe('BraveBidAdapter', function() { creativeId: response_native.seatbid[0].bid[0].crid, dealId: response_native.seatbid[0].bid[0].dealid, mediaType: 'native', - native: {clickUrl: response_native.seatbid[0].bid[0].adm.native.link.url} + native: { clickUrl: response_native.seatbid[0].bid[0].adm.native.link.url } } const nativeResponses = spec.interpretResponse(nativeResponse); diff --git a/test/spec/modules/bridBidAdapter_spec.js b/test/spec/modules/bridBidAdapter_spec.js index 4819f817427..a0e10482d3d 100644 --- a/test/spec/modules/bridBidAdapter_spec.js +++ b/test/spec/modules/bridBidAdapter_spec.js @@ -70,7 +70,7 @@ describe('Brid Bid Adapter', function() { }; const bidderRequest = null; - const bidResponse = spec.interpretResponse({ body: responseBody }, {bidderRequest}); + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); expect(bidResponse.length).to.equal(0); }); @@ -99,7 +99,7 @@ describe('Brid Bid Adapter', function() { bids: videoRequest }; - const bidResponse = spec.interpretResponse({ body: responseBody }, {bidderRequest}); + const bidResponse = spec.interpretResponse({ body: responseBody }, { bidderRequest }); expect(bidResponse).to.not.be.empty; const bid = bidResponse[0]; @@ -161,13 +161,13 @@ describe('Brid Bid Adapter', function() { }); it('Test userSync valid sync url for iframe', function () { - const [userSync] = spec.getUserSyncs({ iframeEnabled: true }, {}, {consentString: 'anyString'}); + const [userSync] = spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: 'anyString' }); expect(userSync.url).to.contain(SYNC_URL + 'load-cookie.html?endpoint=brid&gdpr=0&gdpr_consent=anyString'); expect(userSync.type).to.be.equal('iframe'); }); it('Test userSyncs iframeEnabled=false', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: false}); + const userSyncs = spec.getUserSyncs({ iframeEnabled: false }); expect(userSyncs).to.have.lengthOf(0); }); }); diff --git a/test/spec/modules/bridgewellBidAdapter_spec.js b/test/spec/modules/bridgewellBidAdapter_spec.js index edb8286f931..03b0fff56fd 100644 --- a/test/spec/modules/bridgewellBidAdapter_spec.js +++ b/test/spec/modules/bridgewellBidAdapter_spec.js @@ -5,8 +5,8 @@ import { newBidder } from 'src/adapters/bidderFactory.js'; const userId = { 'criteoId': 'vYlICF9oREZlTHBGRVdrJTJCUUJnc3U2ckNVaXhrV1JWVUZVSUxzZmJlcnJZR0ZxbVhFRnU5bDAlMkJaUWwxWTlNcmdEeHFrJTJGajBWVlV4T3lFQ0FyRVcxNyUyQlIxa0lLSlFhcWJpTm9PSkdPVkx0JTJCbzlQRTQlM0Q', 'pubcid': '074864cb-3705-430e-9ff7-48ccf3c21b94', - 'sharedid': {'id': '01F61MX53D786DSB2WYD38ZVM7', 'third': '01F61MX53D786DSB2WYD38ZVM7'}, - 'uid2': {'id': 'eb33b0cb-8d35-1234-b9c0-1a31d4064777'}, + 'sharedid': { 'id': '01F61MX53D786DSB2WYD38ZVM7', 'third': '01F61MX53D786DSB2WYD38ZVM7' }, + 'uid2': { 'id': 'eb33b0cb-8d35-1234-b9c0-1a31d4064777' }, } const userIdAsEids = [{ source: 'test.org', @@ -416,9 +416,9 @@ describe('bridgewellBidAdapter', function () { expect(payload.bidderRequestsCount).to.equal(3); expect(payload.bidderWinsCount).to.equal(2); expect(payload.deferBilling).to.equal(true); - expect(payload.metrics).to.deep.equal({test: 'metric'}); + expect(payload.metrics).to.deep.equal({ test: 'metric' }); expect(payload.referrer).to.equal('https://www.referrer.com/'); - expect(payload.ortb2).to.deep.equal({site: {name: 'test-site'}}); + expect(payload.ortb2).to.deep.equal({ site: { name: 'test-site' } }); }); }); diff --git a/test/spec/modules/browsiBidAdapter_spec.js b/test/spec/modules/browsiBidAdapter_spec.js index a4f1778af6d..f7a99f014af 100644 --- a/test/spec/modules/browsiBidAdapter_spec.js +++ b/test/spec/modules/browsiBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {ENDPOINT, spec} from 'modules/browsiBidAdapter.js'; -import {config} from 'src/config.js'; -import {VIDEO, BANNER} from 'src/mediaTypes.js'; +import { ENDPOINT, spec } from 'modules/browsiBidAdapter.js'; +import { config } from 'src/config.js'; +import { VIDEO, BANNER } from 'src/mediaTypes.js'; -const {expect} = require('chai'); +const { expect } = require('chai'); const DATA = 'brwvidtag'; const ADAPTER = '__bad'; @@ -52,7 +52,7 @@ describe('browsi Bid Adapter Test', function () { let bidderRequest; beforeEach(function () { window[DATA] = {} - window[DATA][ADAPTER] = {index: 0}; + window[DATA][ADAPTER] = { index: 0 }; bidRequest = [ { 'params': { @@ -76,7 +76,7 @@ describe('browsi Bid Adapter Test', function () { } } }, - 'mediaTypes': {video: {playerSize: [640, 480]}} + 'mediaTypes': { video: { playerSize: [640, 480] } } } ]; bidderRequest = { @@ -119,7 +119,7 @@ describe('browsi Bid Adapter Test', function () { gdpr: bidderRequest.gdprConsent, ccpa: bidderRequest.uspConsent, sizes: inputRequest.sizes, - video: {playerSize: [640, 480]}, + video: { playerSize: [640, 480] }, aUCode: inputRequest.adUnitCode, aID: inputRequest.auctionId, tID: inputRequest.ortb2Imp.ext.tid, @@ -135,7 +135,7 @@ describe('browsi Bid Adapter Test', function () { expect(requests[0].data.timeout).to.equal(8000); }); it('should pass timeout in config', function() { - config.setConfig({'bidderTimeout': 6000}); + config.setConfig({ 'bidderTimeout': 6000 }); const requests = spec.buildRequests(bidRequest, bidderRequest); expect(requests[0].data.timeout).to.equal(6000); }); @@ -186,32 +186,32 @@ describe('browsi Bid Adapter Test', function () { describe('getUserSyncs', function () { const bidResponse = { userSyncs: [ - {url: 'syncUrl1', type: 'image'}, - {url: 'http://syncUrl2', type: 'iframe'} + { url: 'syncUrl1', type: 'image' }, + { url: 'http://syncUrl2', type: 'iframe' } ] } const serverResponse = [ - {body: bidResponse} + { body: bidResponse } ]; it('should return iframe type userSync', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, serverResponse[0]); + const userSyncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, serverResponse[0]); expect(userSyncs.length).to.equal(1); const userSync = userSyncs[0]; expect(userSync.url).to.equal('http://syncUrl2'); expect(userSync.type).to.equal('iframe'); }); it('should return image type userSyncs', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, serverResponse[0]); + const userSyncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, serverResponse[0]); const userSync = userSyncs[0]; expect(userSync.url).to.equal('http://syncUrl1'); expect(userSync.type).to.equal('image'); }); it('should handle multiple server responses', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, serverResponse); + const userSyncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, serverResponse); expect(userSyncs.length).to.equal(1); }); it('should return empty userSyncs', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, serverResponse); + const userSyncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }, serverResponse); expect(userSyncs.length).to.equal(0); }); }); diff --git a/test/spec/modules/bucksenseBidAdapter_spec.js b/test/spec/modules/bucksenseBidAdapter_spec.js index 533dc2f014c..d6417d1bebf 100644 --- a/test/spec/modules/bucksenseBidAdapter_spec.js +++ b/test/spec/modules/bucksenseBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/bucksenseBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/bucksenseBidAdapter.js'; describe('Bucksense Adapter', function() { const BIDDER_CODE = 'bucksense'; @@ -54,12 +54,12 @@ describe('Bucksense Adapter', function() { }, 'mediaTypes': { 'banner': { - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ] + 'sizes': [[300, 250], [300, 600]] } }, 'adUnitCode': 'test-div', 'transactionId': '52b3ed07-2a09-4f58-a426-75acc7602c96', - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ], + 'sizes': [[300, 250], [300, 600]], 'bidId': '22aecdacdcd773', 'bidderRequestId': '1feebcb5938c7e', 'auctionId': '73540558-86cb-4eef-895f-bf99c5353bd7', @@ -109,7 +109,7 @@ describe('Bucksense Adapter', function() { 'params': { 'placementId': '1000' }, - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ] + 'sizes': [[300, 250], [300, 600]] } }; diff --git a/test/spec/modules/buzzoolaBidAdapter_spec.js b/test/spec/modules/buzzoolaBidAdapter_spec.js index 5bb60cd12bd..6fff511852d 100644 --- a/test/spec/modules/buzzoolaBidAdapter_spec.js +++ b/test/spec/modules/buzzoolaBidAdapter_spec.js @@ -1,20 +1,20 @@ -import {expect} from 'chai'; -import {spec} from 'modules/buzzoolaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec } from 'modules/buzzoolaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import '../../../src/prebid.js'; -import {executeRenderer, Renderer} from '../../../src/Renderer.js'; -import {deepClone} from '../../../src/utils.js'; +import { executeRenderer, Renderer } from '../../../src/Renderer.js'; +import { deepClone } from '../../../src/utils.js'; const ENDPOINT = 'https://exchange.buzzoola.com/ssp/prebidjs'; const RENDERER_SRC = 'https://tube.buzzoola.com/new/build/buzzlibrary.js'; const INVALID_BIDS = [{ 'bidder': 'buzzoola', - 'mediaTypes': {'banner': {'sizes': [[240, 400], [300, 600]]}}, + 'mediaTypes': { 'banner': { 'sizes': [[240, 400], [300, 600]] } }, 'sizes': [[240, 400], [300, 600]] }, { 'bidder': 'buzzoola', - 'params': {'placementId': 417846}, + 'params': { 'placementId': 417846 }, 'sizes': [[240, 400], [300, 600]] }, { 'bidder': 'buzzoola', @@ -28,13 +28,13 @@ const INVALID_BIDS = [{ } }, { 'bidder': 'buzzoola', - 'params': {'placementId': 417845} + 'params': { 'placementId': 417845 } }]; const BANNER_BID = { 'bidder': 'buzzoola', - 'params': {'placementId': 417846}, - 'mediaTypes': {'banner': {'sizes': [[240, 400], [300, 600]]}}, + 'params': { 'placementId': 417846 }, + 'mediaTypes': { 'banner': { 'sizes': [[240, 400], [300, 600]] } }, 'sizes': [[240, 400], [300, 600]], 'bidId': '2a11641ada3c6a' }; @@ -79,7 +79,7 @@ const REQUIRED_BANNER_FIELDS = [ const VIDEO_BID = { 'bidder': 'buzzoola', - 'params': {'placementId': 417845}, + 'params': { 'placementId': 417845 }, 'mediaTypes': { 'video': { 'context': 'instream', @@ -140,7 +140,7 @@ const REQUIRED_VIDEO_FIELDS = [ const NATIVE_BID = { 'bidder': 'buzzoola', - 'params': {'placementId': 417845}, + 'params': { 'placementId': 417845 }, 'mediaTypes': { 'native': { 'image': { @@ -296,13 +296,13 @@ describe('buzzoolaBidAdapter', () => { const emptyResponse = ''; function nobidServerResponseCheck(request, response = noBidServerResponse) { - const noBidResult = spec.interpretResponse({body: response}, {data: request}); + const noBidResult = spec.interpretResponse({ body: response }, { data: request }); expect(noBidResult.length).to.equal(0); } function bidServerResponseCheck(response, request, fields) { - const result = spec.interpretResponse({body: response}, {data: request}); + const result = spec.interpretResponse({ body: response }, { data: request }); expect(result).to.deep.equal(response); result.forEach(bid => { @@ -369,7 +369,7 @@ describe('buzzoolaBidAdapter', () => { const scriptStub = sinon.stub(document, 'createElement'); scriptStub.withArgs('script').returns(scriptElement); - result = spec.interpretResponse({body: VIDEO_RESPONSE}, {data: outstreamVideoRequest})[0]; + result = spec.interpretResponse({ body: VIDEO_RESPONSE }, { data: outstreamVideoRequest })[0]; renderer = result.renderer; result.adUnitCode = 'adUnitCode'; diff --git a/test/spec/modules/byDataAnalyticsAdapter_spec.js b/test/spec/modules/byDataAnalyticsAdapter_spec.js index 862a0ee79e5..2fd2efdfe32 100644 --- a/test/spec/modules/byDataAnalyticsAdapter_spec.js +++ b/test/spec/modules/byDataAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ import ascAdapter from 'modules/byDataAnalyticsAdapter'; import { expect } from 'chai'; -import {EVENTS} from 'src/constants.js'; +import { EVENTS } from 'src/constants.js'; const adapterManager = require('src/adapterManager').default; const events = require('src/events'); @@ -36,7 +36,7 @@ const noBidArgs = { bidId: '14480e9832f2d2b', bidder: 'appnexus', bidderRequestId: '13b87b6c20d3636', - mediaTypes: {banner: {sizes: [[300, 250], [250, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [250, 250]] } }, sizes: [[300, 250], [250, 250]], src: 'client', transactionId: 'c8ee3914-1ee0-4ce6-9126-748d5692188c' @@ -57,9 +57,9 @@ const auctionEndArgs = { adUnitCodes: ['div-gpt-ad-mrec1'], adUnits: [{ code: 'div-gpt-ad-mrec1', - mediaTypes: {banner: {sizes: [[300, 250], [250, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [250, 250]] } }, sizes: [[300, 250], [250, 250]], - bids: [{bidder: 'appnexus', params: {placementId: '19305195'}}], + bids: [{ bidder: 'appnexus', params: { placementId: '19305195' } }], transactionId: 'c8ee3914-1ee0-4ce6-9126-748d5692188c' }], auctionEnd: 1627973487504, @@ -80,7 +80,7 @@ const auctionEndArgs = { bidder: 'appnexus', bidderRequestId: '13b87b6c20d3636', src: 'client', - mediaTypes: {banner: {sizes: [[300, 250], [250, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [250, 250]] } }, sizes: [[300, 250], [250, 250]], transactionId: 'c8ee3914-1ee0-4ce6-9126-748d5692188c' } @@ -91,7 +91,7 @@ const expectedDataArgs = { visitor_data: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOiIyNzFhOC0yYjg2LWY0YTQtZjU5YmMiLCJjaWQiOiJhc2MwMDAwMCIsInBpZCI6Ind3dy5sZXRzcnVuLmNvbSIsIm9zIjoiTWFjaW50b3NoIiwib3N2IjoxMC4xNTcsImJyIjoiQ2hyb21lIiwiYnJ2IjoxMDMsInNzIjp7IndpZHRoIjoxNzkyLCJoZWlnaHQiOjExMjB9LCJkZSI6IkRlc2t0b3AiLCJ0eiI6IkFzaWEvQ2FsY3V0dGEifQ.Oj3qnh--t06XO-foVmrMJCGqFfOBed09A-f7LZX5rtfBf4w1_RNRZ4F3on4TMPLonSa7GgzbcEfJS9G_amnleQ', aid: auctionId, as: 1627973484504, - auctionData: [ { + auctionData: [{ au: 'div-gpt-ad-mrec1', auc: 'div-gpt-ad-mrec1', aus: '300x250', diff --git a/test/spec/modules/cadent_aperture_mxBidAdapter_spec.js b/test/spec/modules/cadent_aperture_mxBidAdapter_spec.js index de33d5ff6da..b82b1010d12 100644 --- a/test/spec/modules/cadent_aperture_mxBidAdapter_spec.js +++ b/test/spec/modules/cadent_aperture_mxBidAdapter_spec.js @@ -747,7 +747,7 @@ describe('cadent_aperture_mx Adapter', function () { const vastServerResponse = utils.deepClone(serverResponse); vastServerResponse.seatbid[0].bid[0].adm = ''; vastServerResponse.seatbid[1].bid[0].adm = ''; - const result = spec.interpretResponse({body: vastServerResponse}, bid_outstream); + const result = spec.interpretResponse({ body: vastServerResponse }, bid_outstream); const ad0 = result[0]; const ad1 = result[1]; expect(ad0.renderer).to.exist.and.to.be.a('object'); @@ -779,7 +779,7 @@ describe('cadent_aperture_mx Adapter', function () { it('returns valid advertiser domains', function () { const bidResponse = utils.deepClone(serverResponse); - const result = spec.interpretResponse({body: bidResponse}); + const result = spec.interpretResponse({ body: bidResponse }); expect(result[0].meta.advertiserDomains).to.deep.equal(expectedResponse[0].meta.advertiserDomains); // case where adomains are not in request expect(result[1].meta).to.not.exist; @@ -836,7 +836,7 @@ describe('cadent_aperture_mx Adapter', function () { }); it('should pass gpp string and section id', function() { - const syncs = spec.getUserSyncs({iframeEnabled: true}, {}, {}, {}, { + const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, {}, { gppString: 'abcdefgs', applicableSections: [1, 2, 4] }); diff --git a/test/spec/modules/carodaBidAdapter_spec.js b/test/spec/modules/carodaBidAdapter_spec.js index 063294410da..5a95140c9cc 100644 --- a/test/spec/modules/carodaBidAdapter_spec.js +++ b/test/spec/modules/carodaBidAdapter_spec.js @@ -208,8 +208,8 @@ describe('Caroda adapter', function () { bid_id: 'bidId', params: {}, userIdAsEids: [ - { source: 'adserver.org', uids: [ { id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } } ] }, - { source: 'pubcid.org', uids: [ { id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 } ] } + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ] }]; @@ -297,21 +297,21 @@ describe('Caroda adapter', function () { describe('price floors', function () { it('should not add if floors module not configured', function () { - const validBidRequests = [{ bid_id: 'bidId', params: {ctok: 'ctok1'}, mediaTypes: {video: {}} }]; + const validBidRequests = [{ bid_id: 'bidId', params: { ctok: 'ctok1' }, mediaTypes: { video: {} } }]; const imp = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } })[0].data); assert.equal(imp.bidfloor, undefined); assert.equal(imp.bidfloorcur, undefined); }); it('should not add if floor price not defined', function () { - const validBidRequests = [ getBidWithFloor() ]; + const validBidRequests = [getBidWithFloor()]; const imp = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } })[0].data); assert.equal(imp.bidfloor, undefined); assert.equal(imp.bidfloorcur, 'EUR'); }); it('should request floor price in adserver currency', function () { - const validBidRequests = [ getBidWithFloor() ]; + const validBidRequests = [getBidWithFloor()]; setCurrencyConfig({ adServerCurrency: 'DKK' }); const bidderRequest = { refererInfo: { page: 'page' } }; return addFPDToBidderRequest(bidderRequest).then(res => { @@ -323,7 +323,7 @@ describe('Caroda adapter', function () { }); it('should add correct floor values', function () { - const expectedFloors = [ 1, 1.3, 0.5 ]; + const expectedFloors = [1, 1.3, 0.5]; const validBidRequests = expectedFloors.map(getBidWithFloor); const imps = spec .buildRequests(validBidRequests, { refererInfo: { page: 'page' } }) @@ -367,7 +367,7 @@ describe('Caroda adapter', function () { native: {} } }]; - const [ first, second ] = spec + const [first, second] = spec .buildRequests(validBidRequests, { refererInfo: { page: 'page' } }) .map(r => JSON.parse(r.data)); @@ -392,7 +392,7 @@ describe('Caroda adapter', function () { }]; const { banner } = JSON.parse(spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } })[0].data); assert.deepEqual(banner, { - format: [ { w: 100, h: 100 }, { w: 200, h: 300 } ] + format: [{ w: 100, h: 100 }, { w: 200, h: 300 }] }); }); }); diff --git a/test/spec/modules/categoryTranslation_spec.js b/test/spec/modules/categoryTranslation_spec.js index 3aeca0fbf75..6c3bc41c037 100644 --- a/test/spec/modules/categoryTranslation_spec.js +++ b/test/spec/modules/categoryTranslation_spec.js @@ -2,7 +2,7 @@ import { getAdserverCategoryHook, initTranslation, storage } from 'modules/categ import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import { expect } from 'chai'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; describe('category translation', function () { let getLocalStorageStub; diff --git a/test/spec/modules/ccxBidAdapter_spec.js b/test/spec/modules/ccxBidAdapter_spec.js index 83865c72907..d9742de3a5c 100644 --- a/test/spec/modules/ccxBidAdapter_spec.js +++ b/test/spec/modules/ccxBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; import { spec } from 'modules/ccxBidAdapter.js'; import * as utils from 'src/utils.js'; @@ -84,7 +84,7 @@ describe('ccxAdapter', function () { }); it('Valid bid request - default', function () { - const response = spec.buildRequests(bids, {bids, bidderRequestId: 'id'}); + const response = spec.buildRequests(bids, { bids, bidderRequestId: 'id' }); expect(response).to.be.not.empty; expect(response.data).to.be.not.empty; @@ -171,7 +171,7 @@ describe('ccxAdapter', function () { bidsClone[1].params.video.skip = 1; bidsClone[1].params.video.skipafter = 5; - const response = spec.buildRequests(bidsClone, {'bids': bidsClone}); + const response = spec.buildRequests(bidsClone, { 'bids': bidsClone }); const data = JSON.parse(response.data); expect(data.imp).to.deep.have.same.members(imps); @@ -217,7 +217,7 @@ describe('ccxAdapter', function () { } ]; - const response = spec.buildRequests(bidsClone, {'bids': bidsClone}); + const response = spec.buildRequests(bidsClone, { 'bids': bidsClone }); const data = JSON.parse(response.data); expect(data.imp).to.deep.have.same.members(imps); @@ -246,7 +246,7 @@ describe('ccxAdapter', function () { } ]; - const response = spec.buildRequests(bidsClone, {'bids': bidsClone}); + const response = spec.buildRequests(bidsClone, { 'bids': bidsClone }); const data = JSON.parse(response.data); expect(data.imp).to.deep.have.same.members(imps); @@ -260,7 +260,7 @@ describe('ccxAdapter', function () { consentString: 'awefasdfwefasdfasd', gdprApplies: true }; - const response = spec.buildRequests(bidsClone, {'bids': bidsClone, 'gdprConsent': gdprConsent}); + const response = spec.buildRequests(bidsClone, { 'bids': bidsClone, 'gdprConsent': gdprConsent }); const data = JSON.parse(response.data); expect(data.regs.ext.gdpr).to.equal(1); @@ -270,7 +270,7 @@ describe('ccxAdapter', function () { describe('GDPR absence conformity', function () { it('should transmit correct data', function () { - const response = spec.buildRequests(bids, {bids}); + const response = spec.buildRequests(bids, { bids }); const data = JSON.parse(response.data); expect(data.regs).to.be.undefined; @@ -362,7 +362,7 @@ describe('ccxAdapter', function () { } } ]; - expect(spec.interpretResponse({body: response})).to.deep.have.same.members(bidResponses); + expect(spec.interpretResponse({ body: response })).to.deep.have.same.members(bidResponses); }); it('Valid bid response - single', function () { @@ -383,7 +383,7 @@ describe('ccxAdapter', function () { } } ]; - expect(spec.interpretResponse({body: response})).to.deep.have.same.members(bidResponses); + expect(spec.interpretResponse({ body: response })).to.deep.have.same.members(bidResponses); }); it('Empty bid response', function () { @@ -408,7 +408,7 @@ describe('ccxAdapter', function () { url: 'http://foo.sync?param=2' } ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); + expect(spec.getUserSyncs(syncOptions, [{ body: response }])).to.deep.have.same.members(expectedSyncs); }); it('Valid syncs - only image', function () { @@ -421,23 +421,23 @@ describe('ccxAdapter', function () { type: 'image', url: 'http://foo.sync?param=1' } ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); + expect(spec.getUserSyncs(syncOptions, [{ body: response }])).to.deep.have.same.members(expectedSyncs); }); it('Valid syncs - only iframe', function () { - const syncOptions = {iframeEnabled: true, pixelEnabled: false}; + const syncOptions = { iframeEnabled: true, pixelEnabled: false }; const expectedSyncs = [ { type: 'iframe', url: 'http://foo.sync?param=2' } ]; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.deep.have.same.members(expectedSyncs); + expect(spec.getUserSyncs(syncOptions, [{ body: response }])).to.deep.have.same.members(expectedSyncs); }); it('Valid syncs - empty', function () { - const syncOptions = {iframeEnabled: true, pixelEnabled: true}; + const syncOptions = { iframeEnabled: true, pixelEnabled: true }; response.ext.usersync = {}; - expect(spec.getUserSyncs(syncOptions, [{body: response}])).to.be.empty; + expect(spec.getUserSyncs(syncOptions, [{ body: response }])).to.be.empty; }); }); @@ -489,7 +489,7 @@ describe('ccxAdapter', function () { const bidsClone = utils.deepClone(bids); - const response = spec.buildRequests(bidsClone, {'bids': bidsClone}); + const response = spec.buildRequests(bidsClone, { 'bids': bidsClone }); const data = JSON.parse(response.data); expect(data.imp).to.deep.have.same.members(imps); diff --git a/test/spec/modules/chromeAiRtdProvider_spec.js b/test/spec/modules/chromeAiRtdProvider_spec.js index 744f09ed4df..dfbf454bff9 100644 --- a/test/spec/modules/chromeAiRtdProvider_spec.js +++ b/test/spec/modules/chromeAiRtdProvider_spec.js @@ -135,6 +135,71 @@ describe('Chrome AI RTD Provider', function () { expect(chromeAiRtdProvider.CONSTANTS.SUBMODULE_NAME).to.equal('chromeAi'); expect(chromeAiRtdProvider.CONSTANTS.STORAGE_KEY).to.equal('chromeAi_detected_data'); expect(chromeAiRtdProvider.CONSTANTS.MIN_TEXT_LENGTH).to.be.a('number'); + expect(chromeAiRtdProvider.CONSTANTS.MAX_TEXT_LENGTH).to.be.a('number'); + expect(chromeAiRtdProvider.CONSTANTS.MAX_TEXT_LENGTH).to.equal(1000); + }); + }); + + // Test getPageText and text truncation + describe('getPageText (text truncation)', function () { + // Override document.body.textContent via Object.defineProperty so we can + // control the value returned to getPageText() without mutating the actual + // DOM (which would break the Karma test-runner UI). + function setBodyText(text) { + Object.defineProperty(document.body, 'textContent', { + get: () => text, + configurable: true + }); + } + + afterEach(function () { + // Remove the instance-level override to restore the inherited getter + delete document.body.textContent; + }); + + it('should return null for text shorter than MIN_TEXT_LENGTH', function () { + setBodyText('short'); + const result = chromeAiRtdProvider.getPageText(); + expect(result).to.be.null; + expect(logMessageStub.calledWith(sinon.match('Not enough text content'))).to.be.true; + }); + + it('should return null for empty text', function () { + setBodyText(''); + const result = chromeAiRtdProvider.getPageText(); + expect(result).to.be.null; + }); + + it('should return full text when length is between MIN and MAX', function () { + const text = 'A'.repeat(500); + setBodyText(text); + const result = chromeAiRtdProvider.getPageText(); + expect(result).to.equal(text); + expect(result).to.have.lengthOf(500); + }); + + it('should return text at exactly MAX_TEXT_LENGTH without truncating', function () { + const exactText = 'B'.repeat(chromeAiRtdProvider.CONSTANTS.MAX_TEXT_LENGTH); + setBodyText(exactText); + const result = chromeAiRtdProvider.getPageText(); + expect(result).to.equal(exactText); + expect(logMessageStub.calledWith(sinon.match('Truncating'))).to.be.false; + }); + + it('should truncate text exceeding MAX_TEXT_LENGTH', function () { + const longText = 'C'.repeat(2000); + setBodyText(longText); + const result = chromeAiRtdProvider.getPageText(); + expect(result).to.have.lengthOf(chromeAiRtdProvider.CONSTANTS.MAX_TEXT_LENGTH); + expect(result).to.equal('C'.repeat(1000)); + }); + + it('should log a message when truncating text', function () { + setBodyText('D'.repeat(2000)); + chromeAiRtdProvider.getPageText(); + expect(logMessageStub.calledWith( + sinon.match('Truncating text from 2000 to 1000') + )).to.be.true; }); }); diff --git a/test/spec/modules/clickforceBidAdapter_spec.js b/test/spec/modules/clickforceBidAdapter_spec.js index 42b0f6e5017..e95f7f9af7c 100644 --- a/test/spec/modules/clickforceBidAdapter_spec.js +++ b/test/spec/modules/clickforceBidAdapter_spec.js @@ -160,13 +160,13 @@ describe('ClickforceAdapter', function () { it('should get the correct bid response by display ad', function () { let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('should get the correct bid response by native ad', function () { let bidderRequest; - const result = spec.interpretResponse({ body: response1 }, {bidderRequest}); + const result = spec.interpretResponse({ body: response1 }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse1[0])); }); diff --git a/test/spec/modules/codefuelBidAdapter_spec.js b/test/spec/modules/codefuelBidAdapter_spec.js index 4e891c8ce2c..d304f4bf20c 100644 --- a/test/spec/modules/codefuelBidAdapter_spec.js +++ b/test/spec/modules/codefuelBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/codefuelBidAdapter.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/codefuelBidAdapter.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr'; +import { server } from 'test/mocks/xhr'; const USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/92.0.4515.159 Safari/537.36'; const DEFAULT_USER_AGENT = window.navigator.userAgent; @@ -269,7 +269,7 @@ describe('Codefuel Adapter', function () { ad: '
ad
', width: 300, height: 250, - meta: {'advertiserDomains': []} + meta: { 'advertiserDomains': [] } } ] @@ -294,25 +294,25 @@ describe('Codefuel Adapter', function () { }) it('should not return user sync if pixel enabled with codefuel config', function () { - const ret = spec.getUserSyncs({pixelEnabled: true}) + const ret = spec.getUserSyncs({ pixelEnabled: true }) expect(ret).to.be.an('array').that.is.empty }) it('should not return user sync if pixel disabled', function () { - const ret = spec.getUserSyncs({pixelEnabled: false}) + const ret = spec.getUserSyncs({ pixelEnabled: false }) expect(ret).to.be.an('array').that.is.empty }) it('should not return user sync if url is not set', function () { config.resetConfig() - const ret = spec.getUserSyncs({pixelEnabled: true}) + const ret = spec.getUserSyncs({ pixelEnabled: true }) expect(ret).to.be.an('array').that.is.empty }) it('should not pass GDPR consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.to.be.an('array').that.is.empty - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.be.an('array').that.is.empty - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.be.an('array').that.is.empty + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, undefined)).to.to.be.an('array').that.is.empty + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { gdprApplies: false, consentString: 'foo' }, undefined)).to.be.an('array').that.is.empty + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { gdprApplies: true, consentString: undefined }, undefined)).to.be.an('array').that.is.empty }); it('should not pass US consent', function() { @@ -320,7 +320,7 @@ describe('Codefuel Adapter', function () { }); it('should pass GDPR and US consent', function() { - expect(spec.getUserSyncs({ pixelEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, '1NYN')).to.be.an('array').that.is.empty + expect(spec.getUserSyncs({ pixelEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, '1NYN')).to.be.an('array').that.is.empty }); }) }) diff --git a/test/spec/modules/coinzillaBidAdapter_spec.js b/test/spec/modules/coinzillaBidAdapter_spec.js index 08d6c8aede9..b02f3ccf255 100644 --- a/test/spec/modules/coinzillaBidAdapter_spec.js +++ b/test/spec/modules/coinzillaBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/coinzillaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/coinzillaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; const ENDPOINT_URL = 'https://request.czilladx.com/serve/request.php'; @@ -114,7 +114,7 @@ describe('coinzillaBidAdapter', function () { 'ttl': 3000, 'ad': '

I am an ad

', 'mediaType': 'banner', - 'meta': {'advertiserDomains': ['none.com']} + 'meta': { 'advertiserDomains': ['none.com'] } }]; const result = spec.interpretResponse(serverResponse, bidRequest[0]); expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); diff --git a/test/spec/modules/colossussspBidAdapter_spec.js b/test/spec/modules/colossussspBidAdapter_spec.js index 9c92661fd54..cc926e61b9e 100644 --- a/test/spec/modules/colossussspBidAdapter_spec.js +++ b/test/spec/modules/colossussspBidAdapter_spec.js @@ -447,7 +447,7 @@ describe('ColossussspAdapter', function () { }) describe('getUserSyncs', function () { - const userSync = spec.getUserSyncs({}, {}, { consentString: 'xxx', gdprApplies: 1 }, { consentString: '1YN-' }); + const userSync = spec.getUserSyncs({}, {}, { consentString: 'xxx', gdprApplies: 1 }, '1YN-'); it('Returns valid URL and type', function () { expect(userSync).to.be.an('array').with.lengthOf(1); expect(userSync[0].type).to.exist; diff --git a/test/spec/modules/compassBidAdapter_spec.js b/test/spec/modules/compassBidAdapter_spec.js index 8d0e1cc5715..57412de4379 100644 --- a/test/spec/modules/compassBidAdapter_spec.js +++ b/test/spec/modules/compassBidAdapter_spec.js @@ -482,7 +482,7 @@ describe('CompassBidAdapter', function () { const syncData = config.runWithBidder(bidder, () => spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {})); + }, undefined)); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -491,9 +491,7 @@ describe('CompassBidAdapter', function () { expect(syncData[0].url).to.equal('https://sa-cs.deliverimp.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = config.runWithBidder(bidder, () => spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - })); + const syncData = config.runWithBidder(bidder, () => spec.getUserSyncs({}, {}, {}, '1---')); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -502,7 +500,7 @@ describe('CompassBidAdapter', function () { expect(syncData[0].url).to.equal('https://sa-cs.deliverimp.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = config.runWithBidder(bidder, () => spec.getUserSyncs({}, {}, {}, {}, { + const syncData = config.runWithBidder(bidder, () => spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] })); diff --git a/test/spec/modules/conceptxBidAdapter_spec.js b/test/spec/modules/conceptxBidAdapter_spec.js index 8e9bd2f8cc0..02780045496 100644 --- a/test/spec/modules/conceptxBidAdapter_spec.js +++ b/test/spec/modules/conceptxBidAdapter_spec.js @@ -1,70 +1,75 @@ -// import or require modules necessary for the test, e.g.: -import { expect } from 'chai'; // may prefer 'assert' in place of 'expect' +import { expect } from 'chai'; import { spec } from 'modules/conceptxBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; -// import { config } from 'src/config.js'; describe('conceptxBidAdapter', function () { - const URL = 'https://conceptx.cncpt-central.com/openrtb'; - - const ENDPOINT_URL = `${URL}`; - const ENDPOINT_URL_CONSENT = `${URL}?gdpr_applies=true&consentString=ihaveconsented`; + const ENDPOINT_URL = 'https://cxba-s2s.cncpt.dk/openrtb2/auction'; + const ENDPOINT_URL_CONSENT = + ENDPOINT_URL + '?gdpr_applies=1&gdpr_consent=ihaveconsented'; const adapter = newBidder(spec); const bidderRequests = [ { bidId: '123', bidder: 'conceptx', + adUnitCode: 'div-1', + auctionId: 'auc-1', params: { - site: 'example', - adunit: 'some-id-3' + site: 'example.com', + adunit: 'some-id-3', }, mediaTypes: { banner: { sizes: [[930, 180]], - } + }, }, - } - ] - - const singleBidRequest = { - bid: [ - { - bidId: '123', - } - ] - } + }, + ]; const serverResponse = { body: { - 'bidResponses': [ + id: 'resp-1', + cur: 'DKK', + seatbid: [ { - 'ads': [ + seat: 'conceptx', + bid: [ { - 'referrer': 'http://localhost/prebidpage_concept_bidder.html', - 'ttl': 360, - 'html': '

DUMMY

', - 'requestId': '214dfadd1f8826', - 'cpm': 46, - 'currency': 'DKK', - 'width': 930, - 'height': 180, - 'creativeId': 'FAKE-ID', - 'meta': { - 'mediaType': 'banner' - }, - 'netRevenue': true, - 'destinationUrls': { - 'destination': 'https://concept.dk' - } - } + id: 'bid-1', + impid: '123', + price: 46, + w: 930, + h: 180, + crid: 'FAKE-ID', + adm: '

DUMMY

', + }, ], - 'matchedAdCount': 1, - 'targetId': '214dfadd1f8826' - } - ] - } - } + }, + ], + }, + }; + + const requestPayload = { + data: JSON.stringify({ + id: 'auc-1', + site: { id: 'example.com', domain: 'example.com', page: 'example.com' }, + imp: [ + { + id: '123', + ext: { + prebid: { + storedrequest: { id: 'some-id-3' }, + }, + }, + }, + ], + ext: { + prebid: { + storedrequest: { id: 'cx_global' }, + }, + }, + }), + }; describe('inherited functions', function () { it('exists and is a function', function () { @@ -73,52 +78,105 @@ describe('conceptxBidAdapter', function () { }); describe('isBidRequestValid', function () { - it('should return true when required params found', function () { + it('should return true when bidId and params.adunit are present', function () { expect(spec.isBidRequestValid(bidderRequests[0])).to.equal(true); }); + + it('should return false when params.adunit is missing', function () { + expect( + spec.isBidRequestValid({ + bidId: '123', + bidder: 'conceptx', + params: { site: 'example' }, + }) + ).to.equal(false); + }); + + it('should return false when bidId is missing', function () { + expect( + spec.isBidRequestValid({ + bidder: 'conceptx', + params: { site: 'example', adunit: 'id-1' }, + }) + ).to.equal(false); + }); }); describe('buildRequests', function () { - it('Test requests', function () { - const request = spec.buildRequests(bidderRequests, {}); - expect(request.length).to.equal(1); - expect(request[0]).to.have.property('data'); - const bid = JSON.parse(request[0].data).adUnits[0] - expect(bid.site).to.equal('example'); - expect(bid.adunit).to.equal('some-id-3'); - expect(JSON.stringify(bid.dimensions)).to.equal(JSON.stringify([ - [930, 180]])); + it('should build OpenRTB request with stored requests', function () { + const requests = spec.buildRequests(bidderRequests, {}); + expect(requests).to.have.lengthOf(1); + expect(requests[0]).to.have.property('method', 'POST'); + expect(requests[0]).to.have.property('url', ENDPOINT_URL); + expect(requests[0]).to.have.property('data'); + + const payload = JSON.parse(requests[0].data); + expect(payload).to.have.property('site'); + expect(payload.site).to.have.property('id', 'example.com'); + expect(payload).to.have.property('imp'); + expect(payload.imp).to.have.lengthOf(1); + expect(payload.imp[0].ext.prebid.storedrequest).to.deep.equal({ + id: 'some-id-3', + }); + expect(payload.ext.prebid.storedrequest).to.deep.equal({ + id: 'cx_global', + }); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 930, h: 180 }]); + }); + + it('should include withCredentials in options', function () { + const requests = spec.buildRequests(bidderRequests, {}); + expect(requests[0].options).to.deep.include({ withCredentials: true }); }); }); describe('user privacy', function () { - it('should NOT send GDPR Consent data if gdprApplies equals undefined', function () { - const request = spec.buildRequests(bidderRequests, { gdprConsent: { gdprApplies: undefined, consentString: 'iDoNotConsent' } }); - expect(request.length).to.equal(1); - expect(request[0]).to.have.property('url') - expect(request[0].url).to.equal(ENDPOINT_URL); + it('should NOT add GDPR params to URL when gdprApplies is undefined', function () { + const requests = spec.buildRequests(bidderRequests, { + gdprConsent: { gdprApplies: undefined, consentString: 'iDoNotConsent' }, + }); + expect(requests[0].url).to.equal(ENDPOINT_URL); }); - it('should send GDPR Consent data if gdprApplies', function () { - const request = spec.buildRequests(bidderRequests, { gdprConsent: { gdprApplies: true, consentString: 'ihaveconsented' } }); - expect(request.length).to.equal(1); - expect(request[0]).to.have.property('url') - expect(request[0].url).to.equal(ENDPOINT_URL_CONSENT); + + it('should add gdpr_applies and gdpr_consent to URL when GDPR applies', function () { + const requests = spec.buildRequests(bidderRequests, { + gdprConsent: { gdprApplies: true, consentString: 'ihaveconsented' }, + }); + expect(requests[0].url).to.include('gdpr_applies=1'); + expect(requests[0].url).to.include('gdpr_consent=ihaveconsented'); }); }); describe('interpretResponse', function () { - it('should return valid response when passed valid server response', function () { - const interpretedResponse = spec.interpretResponse(serverResponse, singleBidRequest); - const ad = serverResponse.body.bidResponses[0].ads[0] - expect(interpretedResponse).to.have.lengthOf(1); - expect(interpretedResponse[0].cpm).to.equal(ad.cpm); - expect(interpretedResponse[0].width).to.equal(Number(ad.width)); - expect(interpretedResponse[0].height).to.equal(Number(ad.height)); - expect(interpretedResponse[0].creativeId).to.equal(ad.creativeId); - expect(interpretedResponse[0].currency).to.equal(ad.currency); - expect(interpretedResponse[0].netRevenue).to.equal(true); - expect(interpretedResponse[0].ad).to.equal(ad.html); - expect(interpretedResponse[0].ttl).to.equal(360); + it('should return valid bids from PBS seatbid format', function () { + const interpreted = spec.interpretResponse(serverResponse, requestPayload); + expect(interpreted).to.have.lengthOf(1); + expect(interpreted[0].requestId).to.equal('123'); + expect(interpreted[0].cpm).to.equal(46); + expect(interpreted[0].width).to.equal(930); + expect(interpreted[0].height).to.equal(180); + expect(interpreted[0].creativeId).to.equal('FAKE-ID'); + expect(interpreted[0].currency).to.equal('DKK'); + expect(interpreted[0].netRevenue).to.equal(true); + expect(interpreted[0].ad).to.equal('

DUMMY

'); + expect(interpreted[0].ttl).to.equal(300); + }); + + it('should return empty array when no seatbid', function () { + const emptyResponse = { body: { seatbid: [] } }; + expect(spec.interpretResponse(emptyResponse, {})).to.deep.equal([]); + }); + + it('should return empty array when seatbid is missing', function () { + const noSeatbid = { body: {} }; + expect(spec.interpretResponse(noSeatbid, {})).to.deep.equal([]); + }); + }); + + describe('getUserSyncs', function () { + it('should return empty array (sync handled by runPbsCookieSync)', function () { + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [], {}, '', {}); + expect(syncs).to.deep.equal([]); }); }); }); diff --git a/test/spec/modules/concertAnalyticsAdapter_spec.js b/test/spec/modules/concertAnalyticsAdapter_spec.js index 639011ac481..054af3e18e6 100644 --- a/test/spec/modules/concertAnalyticsAdapter_spec.js +++ b/test/spec/modules/concertAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ import concertAnalytics from 'modules/concertAnalyticsAdapter.js'; import { expect } from 'chai'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expectEvents } from '../../helpers/analytics.js'; import { EVENTS } from 'src/constants.js'; import { server } from 'test/mocks/xhr.js'; diff --git a/test/spec/modules/concertBidAdapter_spec.js b/test/spec/modules/concertBidAdapter_spec.js index 6c842e58d37..3ba309f029f 100644 --- a/test/spec/modules/concertBidAdapter_spec.js +++ b/test/spec/modules/concertBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import sinon from 'sinon'; import { spec, storage } from 'modules/concertBidAdapter.js'; import { hook } from 'src/hook.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('ConcertAdapter', function () { let bidRequests; @@ -301,7 +301,7 @@ describe('ConcertAdapter', function () { }); it('should return empty bids if there are no bids from the server', function() { - const bids = spec.interpretResponse({ body: {bids: []} }, bidRequest); + const bids = spec.interpretResponse({ body: { bids: [] } }, bidRequest); expect(bids).to.have.lengthOf(0); }); }); diff --git a/test/spec/modules/connatixBidAdapter_spec.js b/test/spec/modules/connatixBidAdapter_spec.js index 35e60c403af..1ed05f53009 100644 --- a/test/spec/modules/connatixBidAdapter_spec.js +++ b/test/spec/modules/connatixBidAdapter_spec.js @@ -142,10 +142,12 @@ describe('connatixBidAdapter', function () { let element; let getBoundingClientRectStub; let topWinMock; + let sandbox; beforeEach(() => { + sandbox = sinon.createSandbox(); element = document.createElement('div'); - getBoundingClientRectStub = sinon.stub(element, 'getBoundingClientRect'); + getBoundingClientRectStub = sandbox.stub(element, 'getBoundingClientRect'); topWinMock = { document: { @@ -154,10 +156,18 @@ describe('connatixBidAdapter', function () { innerWidth: 800, innerHeight: 600 }; + sandbox.stub(winDimensions, 'getWinDimensions').callsFake(() => ({ + document: { + documentElement: { + clientWidth: topWinMock.innerWidth, + clientHeight: topWinMock.innerHeight + } + } + })); }); afterEach(() => { - getBoundingClientRectStub.restore(); + sandbox.restore(); }); it('should return 0 if the document is not visible', () => { @@ -180,25 +190,18 @@ describe('connatixBidAdapter', function () { it('should return the correct percentage if the element is partially in view', () => { const boundingBox = { left: 700, top: 500, right: 900, bottom: 700, width: 200, height: 200 }; getBoundingClientRectStub.returns(boundingBox); - const getWinDimensionsStub = sinon.stub(winDimensions, 'getWinDimensions'); - getWinDimensionsStub.returns({ innerWidth: topWinMock.innerWidth, innerHeight: topWinMock.innerHeight}); - const viewability = connatixGetViewability(element, topWinMock); expect(viewability).to.equal(25); // 100x100 / 200x200 = 0.25 -> 25% - getWinDimensionsStub.restore(); }); it('should return 0% if the element is not in view', () => { - const getWinDimensionsStub = sinon.stub(winDimensions, 'getWinDimensions'); - getWinDimensionsStub.returns({ innerWidth: topWinMock.innerWidth, innerHeight: topWinMock.innerHeight}); const boundingBox = { left: 900, top: 700, right: 1100, bottom: 900, width: 200, height: 200 }; getBoundingClientRectStub.returns(boundingBox); const viewability = connatixGetViewability(element, topWinMock); expect(viewability).to.equal(0); - getWinDimensionsStub.restore(); }); it('should use provided width and height if element dimensions are zero', () => { @@ -218,10 +221,12 @@ describe('connatixBidAdapter', function () { let topWinMock; let querySelectorStub; let getElementByIdStub; + let sandbox; beforeEach(() => { + sandbox = sinon.createSandbox(); element = document.createElement('div'); - getBoundingClientRectStub = sinon.stub(element, 'getBoundingClientRect'); + getBoundingClientRectStub = sandbox.stub(element, 'getBoundingClientRect'); topWinMock = { document: { @@ -231,14 +236,22 @@ describe('connatixBidAdapter', function () { innerHeight: 600 }; - querySelectorStub = sinon.stub(window.top.document, 'querySelector'); - getElementByIdStub = sinon.stub(document, 'getElementById'); + querySelectorStub = sandbox.stub(window.top.document, 'querySelector'); + getElementByIdStub = sandbox.stub(document, 'getElementById'); + sandbox.stub(winDimensions, 'getWinDimensions').callsFake(() => ( + { + document: { + documentElement: { + clientWidth: topWinMock.innerWidth, + clientHeight: topWinMock.innerHeight + } + } + } + )); }); afterEach(() => { - getBoundingClientRectStub.restore(); - querySelectorStub.restore(); - getElementByIdStub.restore(); + sandbox.restore(); }); it('should return 100% viewability when the element is fully within view and has a valid viewabilityContainerIdentifier', () => { @@ -650,13 +663,13 @@ describe('connatixBidAdapter', function () { describe('interpretResponse', function () { const CustomerId = '99f20d18-c4b4-4a28-3d8e-d43e2c8cb4ac'; const PlayerId = 'e4984e88-9ff4-45a3-8b9d-33aabcad634f'; - const Bid = {Cpm: 0.1, RequestId: '2f897340c4eaa3', Ttl: 86400, CustomerId, PlayerId, Lurl: 'test-lurl'}; + const Bid = { Cpm: 0.1, RequestId: '2f897340c4eaa3', Ttl: 86400, CustomerId, PlayerId, Lurl: 'test-lurl' }; let serverResponse; this.beforeEach(function () { serverResponse = { body: { - Bids: [ Bid ] + Bids: [Bid] }, headers: function() { } }; @@ -683,7 +696,7 @@ describe('connatixBidAdapter', function () { it('Should contains the same values as in the serverResponse', function() { const bidResponses = spec.interpretResponse(serverResponse); - const [ bidResponse ] = bidResponses; + const [bidResponse] = bidResponses; expect(bidResponse.requestId).to.equal(serverResponse.body.Bids[0].RequestId); expect(bidResponse.cpm).to.equal(serverResponse.body.Bids[0].Cpm); expect(bidResponse.ttl).to.equal(serverResponse.body.Bids[0].Ttl); @@ -694,7 +707,7 @@ describe('connatixBidAdapter', function () { }); it('Should return n bid responses for n bids', function() { - serverResponse.body.Bids = [ { ...Bid }, { ...Bid } ]; + serverResponse.body.Bids = [{ ...Bid }, { ...Bid }]; const firstBidCpm = 4; serverResponse.body.Bids[0].Cpm = firstBidCpm; @@ -711,10 +724,10 @@ describe('connatixBidAdapter', function () { it('Should contain specific values for banner bids', function () { const adHtml = 'ad html' - serverResponse.body.Bids = [ { ...Bid, Ad: adHtml } ]; + serverResponse.body.Bids = [{ ...Bid, Ad: adHtml }]; const bidResponses = spec.interpretResponse(serverResponse); - const [ bidResponse ] = bidResponses; + const [bidResponse] = bidResponses; expect(bidResponse.vastXml).to.be.undefined; expect(bidResponse.ad).to.equal(adHtml); @@ -723,10 +736,10 @@ describe('connatixBidAdapter', function () { it('Should contain specific values for video bids', function () { const adVastXml = 'ad vast xml' - serverResponse.body.Bids = [ { ...Bid, VastXml: adVastXml } ]; + serverResponse.body.Bids = [{ ...Bid, VastXml: adVastXml }]; const bidResponses = spec.interpretResponse(serverResponse); - const [ bidResponse ] = bidResponses; + const [bidResponse] = bidResponses; expect(bidResponse.ad).to.be.undefined; expect(bidResponse.vastXml).to.equal(adVastXml); @@ -739,19 +752,19 @@ describe('connatixBidAdapter', function () { const PlayerId = 'e4984e88-9ff4-45a3-8b9d-33aabcad634f'; const UserSyncEndpoint = 'https://connatix.com/sync' const UserSyncEndpointWithParams = 'https://connatix.com/sync?param1=value1' - const Bid = {Cpm: 0.1, RequestId: '2f897340c4eaa3', Ttl: 86400, CustomerId, PlayerId}; + const Bid = { Cpm: 0.1, RequestId: '2f897340c4eaa3', Ttl: 86400, CustomerId, PlayerId }; const serverResponse = { body: { UserSyncEndpoint, - Bids: [ Bid ] + Bids: [Bid] }, headers: function() { } }; const serverResponse2 = { body: { UserSyncEndpoint: UserSyncEndpointWithParams, - Bids: [ Bid ] + Bids: [Bid] }, headers: function() { } }; @@ -761,30 +774,30 @@ describe('connatixBidAdapter', function () { }); it('Should return an empty array when iframeEnabled: false', function () { - expect(spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [], {}, {}, {})).to.be.an('array').that.is.empty; + expect(spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [], {}, {}, {})).to.be.an('array').that.is.empty; }); it('Should return an empty array when serverResponses is emprt array', function () { - expect(spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [], {}, {}, {})).to.be.an('array').that.is.empty; + expect(spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [], {}, {}, {})).to.be.an('array').that.is.empty; }); it('Should return an empty array when iframeEnabled: true but serverResponses in an empty array', function () { - expect(spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [serverResponse], {}, {}, {})).to.be.an('array').that.is.empty; + expect(spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [serverResponse], {}, {}, {})).to.be.an('array').that.is.empty; }); it('Should return an empty array when iframeEnabled: true but serverResponses in an not defined or null', function () { - expect(spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, undefined, {}, {}, {})).to.be.an('array').that.is.empty; - expect(spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, null, {}, {}, {})).to.be.an('array').that.is.empty; + expect(spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, undefined, {}, {}, {})).to.be.an('array').that.is.empty; + expect(spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, null, {}, {}, {})).to.be.an('array').that.is.empty; }); it('Should return one user sync object when iframeEnabled is true and serverResponses is not an empry array', function () { - expect(spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [serverResponse], {}, {}, {})).to.be.an('array').that.is.not.empty; + expect(spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [serverResponse], {}, {}, {})).to.be.an('array').that.is.not.empty; }); it('Should return a list containing a single object having type: iframe and url: syncUrl', function () { - const userSyncList = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [serverResponse], undefined, undefined, undefined); + const userSyncList = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [serverResponse], undefined, undefined, undefined); const { type, url } = userSyncList[0]; expect(type).to.equal('iframe'); expect(url).to.equal(UserSyncEndpoint); }); it('Should append gdpr: 0 if gdprConsent object is provided but gdprApplies field is not provided', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], {}, undefined, @@ -795,9 +808,9 @@ describe('connatixBidAdapter', function () { }); it('Should append gdpr having the value of gdprApplied if gdprConsent object is present and have gdprApplies field', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true}, + { gdprApplies: true }, undefined, undefined ); @@ -806,9 +819,9 @@ describe('connatixBidAdapter', function () { }); it('Should append gdpr_consent if gdprConsent object is present and have gdprApplies field', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true, consentString: 'alabala'}, + { gdprApplies: true, consentString: 'alabala' }, undefined, undefined ); @@ -817,9 +830,9 @@ describe('connatixBidAdapter', function () { }); it('Should encodeURI gdpr_consent corectly', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true, consentString: 'test&2'}, + { gdprApplies: true, consentString: 'test&2' }, undefined, undefined ); @@ -828,9 +841,9 @@ describe('connatixBidAdapter', function () { }); it('Should append usp_consent to the url if uspConsent is provided', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true, consentString: 'test&2'}, + { gdprApplies: true, consentString: 'test&2' }, '1YYYN', undefined ); @@ -839,22 +852,22 @@ describe('connatixBidAdapter', function () { }); it('Should append gpp and gpp_sid to the url if gppConsent param is provided', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true, consentString: 'test&2'}, + { gdprApplies: true, consentString: 'test&2' }, '1YYYN', - {gppString: 'GPP', applicableSections: [2, 4]} + { gppString: 'GPP', applicableSections: [2, 4] } ); const { url } = userSyncList[0]; expect(url).to.equal(`${UserSyncEndpoint}?gdpr=1&gdpr_consent=test%262&us_privacy=1YYYN&gpp=GPP&gpp_sid=2,4`); }); it('Should correctly append all consents to the sync url if the url contains query params', function () { const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse2], - {gdprApplies: true, consentString: 'test&2'}, + { gdprApplies: true, consentString: 'test&2' }, '1YYYN', - {gppString: 'GPP', applicableSections: [2, 4]} + { gppString: 'GPP', applicableSections: [2, 4] } ); const { url } = userSyncList[0]; expect(url).to.equal(`${UserSyncEndpointWithParams}&gdpr=1&gdpr_consent=test%262&us_privacy=1YYYN&gpp=GPP&gpp_sid=2,4`); @@ -864,11 +877,11 @@ describe('connatixBidAdapter', function () { coppa: true }); const userSyncList = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [serverResponse], - {gdprApplies: true, consentString: 'test&2'}, + { gdprApplies: true, consentString: 'test&2' }, '1YYYN', - {gppString: 'GPP', applicableSections: [2, 4]} + { gppString: 'GPP', applicableSections: [2, 4] } ); const { url } = userSyncList[0]; expect(url).to.equal(`${UserSyncEndpoint}?gdpr=1&gdpr_consent=test%262&us_privacy=1YYYN&gpp=GPP&gpp_sid=2,4&coppa=1`); diff --git a/test/spec/modules/connectIdSystem_spec.js b/test/spec/modules/connectIdSystem_spec.js index 48ef3a30fe3..e30547a4a12 100644 --- a/test/spec/modules/connectIdSystem_spec.js +++ b/test/spec/modules/connectIdSystem_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {connectIdSubmodule, storage} from 'modules/connectIdSystem.js'; -import {server} from '../../mocks/xhr.js'; -import {parseQS, parseUrl} from 'src/utils.js'; +import { expect } from 'chai'; +import { connectIdSubmodule, storage } from 'modules/connectIdSystem.js'; +import { server } from '../../mocks/xhr.js'; +import { parseQS, parseUrl } from 'src/utils.js'; import * as refererDetection from '../../../src/refererDetection.js'; const TEST_SERVER_URL = 'http://localhost:9876/'; @@ -96,20 +96,20 @@ describe('Yahoo ConnectID Submodule', () => { { detail: 'cookie data over local storage data', cookie: '{"connectId":"foo"}', - localStorage: JSON.stringify({connectId: 'bar'}), - expected: {connectId: 'foo'} + localStorage: JSON.stringify({ connectId: 'bar' }), + expected: { connectId: 'foo' } }, { detail: 'cookie data if only cookie data exists', cookie: '{"connectId":"foo"}', localStorage: undefined, - expected: {connectId: 'foo'} + expected: { connectId: 'foo' } }, { detail: 'local storage data if only it local storage data exists', cookie: undefined, - localStorage: JSON.stringify({connectId: 'bar'}), - expected: {connectId: 'bar'} + localStorage: JSON.stringify({ connectId: 'bar' }), + expected: { connectId: 'bar' } }, { detail: 'undefined when both cookie and local storage are empty', @@ -150,7 +150,7 @@ describe('Yahoo ConnectID Submodule', () => { describe('with valid module configuration', () => { describe('when data is in client storage', () => { it('returns an object with the stored ID from cookies for valid module configuration and sync is done', () => { - const cookieData = {connectId: 'foobar'}; + const cookieData = { connectId: 'foobar' }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -164,7 +164,7 @@ describe('Yahoo ConnectID Submodule', () => { it('returns an object with the stored ID from cookies for valid module configuration with no user sync', () => { const last13Days = Date.now() - (60 * 60 * 24 * 1000 * 13); - const cookieData = {connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days}; + const cookieData = { connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -179,11 +179,11 @@ describe('Yahoo ConnectID Submodule', () => { it('returns an object with the stored ID and refreshes the storages with the new lastUsed', () => { const last13Days = Date.now() - (60 * 60 * 24 * 1000 * 13); - const cookieData = {connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days, lastUsed: 1}; + const cookieData = { connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days, lastUsed: 1 }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(20); - const newCookieData = Object.assign({}, cookieData, {lastUsed: 20}) + const newCookieData = Object.assign({}, cookieData, { lastUsed: 20 }) const result = invokeGetIdAPI({ he: HASHED_EMAIL, pixelId: PIXEL_ID @@ -203,7 +203,7 @@ describe('Yahoo ConnectID Submodule', () => { it('returns an object with the stored ID from cookies and no sync when puid stays the same', () => { const last13Days = Date.now() - (60 * 60 * 24 * 1000 * 13); - const cookieData = {connectId: 'foobar', puid: '123', lastSynced: last13Days}; + const cookieData = { connectId: 'foobar', puid: '123', lastSynced: last13Days }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(20); @@ -221,7 +221,7 @@ describe('Yahoo ConnectID Submodule', () => { it('returns an object with the stored ID from cookies and syncs because of expired auto generated puid', () => { const last13Days = Date.now() - (60 * 60 * 24 * 1000 * 13); const last31Days = Date.now() - (60 * 60 * 24 * 1000 * 31); - const cookieData = {connectId: 'foo', he: 'email', lastSynced: last13Days, puid: '9', lastUsed: last31Days}; + const cookieData = { connectId: 'foo', he: 'email', lastSynced: last13Days, puid: '9', lastUsed: last31Days }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -259,7 +259,7 @@ describe('Yahoo ConnectID Submodule', () => { }); it('returns an object with the stored ID from localStorage for valid module configuration and sync is done', () => { - const localStorageData = {connectId: 'foobarbaz'}; + const localStorageData = { connectId: 'foobarbaz' }; getLocalStorageStub.withArgs(STORAGE_KEY).returns(localStorageData); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -272,7 +272,7 @@ describe('Yahoo ConnectID Submodule', () => { }); it('returns an object with the stored ID from localStorage and refreshes the cookie storage', () => { - const localStorageData = {connectId: 'foobarbaz'}; + const localStorageData = { connectId: 'foobarbaz' }; getLocalStorageStub.withArgs(STORAGE_KEY).returns(localStorageData); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(1); @@ -294,7 +294,7 @@ describe('Yahoo ConnectID Submodule', () => { const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2); const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21); const ttl = 10000; - const cookieData = {connectId: 'foo', he: 'email', lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl}; + const cookieData = { connectId: 'foo', he: 'email', lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ @@ -311,7 +311,7 @@ describe('Yahoo ConnectID Submodule', () => { const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2); const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21); const ttl = 60 * 60 * 24 * 1000 * 3; - const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl}; + const cookieData = { connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ @@ -328,7 +328,7 @@ describe('Yahoo ConnectID Submodule', () => { const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2); const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21); const ttl = 60 * 60 * 24 * 1000 * 3; - const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl}; + const cookieData = { connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const result = invokeGetIdAPI({ @@ -346,7 +346,7 @@ describe('Yahoo ConnectID Submodule', () => { const last2Days = Date.now() - (60 * 60 * 24 * 1000 * 2); const last21Days = Date.now() - (60 * 60 * 24 * 1000 * 21); const ttl = 60 * 60 * 24 * 1000 * 3; - const cookieData = {connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl}; + const cookieData = { connectId: 'foo', he: HASHED_EMAIL, lastSynced: last2Days, puid: '9', lastUsed: last21Days, ttl }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const getRefererInfoStub = sinon.stub(refererDetection, 'getRefererInfo'); getRefererInfoStub.returns({ @@ -396,7 +396,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the production API endpoint without the stored puid after 30 days', () => { @@ -430,7 +430,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the production API endpoint with provided puid', () => { @@ -465,11 +465,11 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('deletes local storage data when expiry has passed', () => { - const localStorageData = {connectId: 'foobarbaz', __expires: Date.now() - 10000}; + const localStorageData = { connectId: 'foobarbaz', __expires: Date.now() - 10000 }; getLocalStorageStub.withArgs(STORAGE_KEY).returns(localStorageData); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -482,7 +482,7 @@ describe('Yahoo ConnectID Submodule', () => { }); it('will not delete local storage data when expiry has not passed', () => { - const localStorageData = {connectId: 'foobarbaz', __expires: Date.now() + 10000}; + const localStorageData = { connectId: 'foobarbaz', __expires: Date.now() + 10000 }; getLocalStorageStub.withArgs(STORAGE_KEY).returns(localStorageData); const result = invokeGetIdAPI({ he: HASHED_EMAIL, @@ -596,7 +596,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the production API endpoint with pixelId and puid query params', () => { @@ -621,7 +621,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the production API endpoint with pixelId, puid and he query params', () => { @@ -648,7 +648,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${PROD_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the specified override API endpoint with query params', () => { @@ -672,7 +672,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${OVERRIDE_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('Makes an ajax GET request to the specified override API endpoint without GPP', () => { @@ -695,7 +695,7 @@ describe('Yahoo ConnectID Submodule', () => { expect(ajaxStub.firstCall.args[0].indexOf(`${OVERRIDE_ENDPOINT}?`)).to.equal(0); expect(requestQueryParams).to.deep.equal(expectedParams); - expect(ajaxStub.firstCall.args[3]).to.deep.equal({method: 'GET', withCredentials: true}); + expect(ajaxStub.firstCall.args[3]).to.deep.equal({ method: 'GET', withCredentials: true }); }); it('sets the callbacks param of the ajax function call correctly', () => { @@ -748,7 +748,7 @@ describe('Yahoo ConnectID Submodule', () => { const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(0); getAjaxFnStub.restore(); - const upsResponse = {connectid: 'foobarbaz'}; + const upsResponse = { connectid: 'foobarbaz' }; const expiryDelta = new Date(60 * 60 * 24 * 365 * 1000); invokeGetIdAPI({ puid: PUBLISHER_USER_ID, @@ -757,7 +757,7 @@ describe('Yahoo ConnectID Submodule', () => { const request = server.requests[0]; request.respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(upsResponse) ); const storage = Object.assign({}, upsResponse, { @@ -784,7 +784,7 @@ describe('Yahoo ConnectID Submodule', () => { cookiesEnabledStub.returns(false); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(0); - const upsResponse = {connectid: 'barfoo'}; + const upsResponse = { connectid: 'barfoo' }; const expectedStoredData = { connectid: 'barfoo', puid: PUBLISHER_USER_ID, @@ -798,7 +798,7 @@ describe('Yahoo ConnectID Submodule', () => { const request = server.requests[0]; request.respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(upsResponse) ); dateNowStub.restore(); @@ -812,7 +812,7 @@ describe('Yahoo ConnectID Submodule', () => { getAjaxFnStub.restore(); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(0); - const upsResponse = {connectid: 'html5only'}; + const upsResponse = { connectid: 'html5only' }; const expectedStoredData = { connectid: 'html5only', puid: PUBLISHER_USER_ID, @@ -822,11 +822,11 @@ describe('Yahoo ConnectID Submodule', () => { invokeGetIdAPI({ puid: PUBLISHER_USER_ID, pixelId: PIXEL_ID - }, consentData, {type: 'html5'}); + }, consentData, { type: 'html5' }); const request = server.requests[0]; request.respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(upsResponse) ); dateNowStub.restore(); @@ -841,7 +841,7 @@ describe('Yahoo ConnectID Submodule', () => { getAjaxFnStub.restore(); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(0); - const upsResponse = {connectid: 'cookieonly'}; + const upsResponse = { connectid: 'cookieonly' }; const expectedStoredData = { connectid: 'cookieonly', puid: PUBLISHER_USER_ID, @@ -852,11 +852,11 @@ describe('Yahoo ConnectID Submodule', () => { invokeGetIdAPI({ puid: PUBLISHER_USER_ID, pixelId: PIXEL_ID - }, consentData, {type: 'cookie'}); + }, consentData, { type: 'cookie' }); const request = server.requests[0]; request.respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(upsResponse) ); dateNowStub.restore(); @@ -869,27 +869,27 @@ describe('Yahoo ConnectID Submodule', () => { }); it('does not sync localStorage to cookie when storage type is html5', () => { - const localStorageData = {connectId: 'foobarbaz'}; + const localStorageData = { connectId: 'foobarbaz' }; getLocalStorageStub.withArgs(STORAGE_KEY).returns(localStorageData); invokeGetIdAPI({ he: HASHED_EMAIL, pixelId: PIXEL_ID - }, consentData, {type: 'html5'}); + }, consentData, { type: 'html5' }); expect(setCookieStub.called).to.be.false; }); it('updates existing ID with html5 storage type without writing cookie', () => { const last13Days = Date.now() - (60 * 60 * 24 * 1000 * 13); - const cookieData = {connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days}; + const cookieData = { connectId: 'foobar', he: HASHED_EMAIL, lastSynced: last13Days }; getCookieStub.withArgs(STORAGE_KEY).returns(JSON.stringify(cookieData)); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(20); - const newCookieData = Object.assign({}, cookieData, {lastUsed: 20}) + const newCookieData = Object.assign({}, cookieData, { lastUsed: 20 }) const result = invokeGetIdAPI({ he: HASHED_EMAIL, pixelId: PIXEL_ID - }, consentData, {type: 'html5'}); + }, consentData, { type: 'html5' }); dateNowStub.restore(); expect(result).to.be.an('object').that.has.all.keys('id'); @@ -903,7 +903,7 @@ describe('Yahoo ConnectID Submodule', () => { getAjaxFnStub.restore(); const dateNowStub = sinon.stub(Date, 'now'); dateNowStub.returns(0); - const upsResponse = {connectid: 'both'}; + const upsResponse = { connectid: 'both' }; const expectedStoredData = { connectid: 'both', puid: PUBLISHER_USER_ID, @@ -914,11 +914,11 @@ describe('Yahoo ConnectID Submodule', () => { invokeGetIdAPI({ puid: PUBLISHER_USER_ID, pixelId: PIXEL_ID - }, consentData, {type: 'cookie&html5'}); + }, consentData, { type: 'cookie&html5' }); const request = server.requests[0]; request.respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(upsResponse) ); dateNowStub.restore(); @@ -982,12 +982,12 @@ describe('Yahoo ConnectID Submodule', () => { VALID_API_RESPONSES.forEach(responseData => { it('should return a newly constructed object with the connect ID for a payload with ${responseData.key} key(s)', () => { expect(connectIdSubmodule.decode(responseData.payload)).to.deep.equal( - {connectId: responseData.expected} + { connectId: responseData.expected } ); }); }); - [{}, '', {foo: 'bar'}].forEach((response) => { + [{}, '', { foo: 'bar' }].forEach((response) => { it(`should return undefined for an invalid response "${JSON.stringify(response)}"`, () => { expect(connectIdSubmodule.decode(response)).to.be.undefined; }); diff --git a/test/spec/modules/connectadBidAdapter_spec.js b/test/spec/modules/connectadBidAdapter_spec.js index 724f4eb93d4..92431c1265a 100644 --- a/test/spec/modules/connectadBidAdapter_spec.js +++ b/test/spec/modules/connectadBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/connectadBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/connectadBidAdapter.js'; import { config } from 'src/config.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import assert from 'assert'; describe('ConnectAd Adapter', function () { @@ -357,10 +357,10 @@ describe('ConnectAd Adapter', function () { const data = JSON.parse(request.data); expect(data.bcat).to.deep.equal(localBidderRequest.ortb2.bcat); expect(data.badv).to.deep.equal(localBidderRequest.ortb2.badv); - expect(data.site).to.nested.include({'ext.data': 'some site data'}); - expect(data.device).to.nested.include({'ext.data': 'some device data'}); - expect(data.user).to.nested.include({'ext.data': 'some user data'}); - expect(data.regs).to.nested.include({'ext.data': 'some regs data'}); + expect(data.site).to.nested.include({ 'ext.data': 'some site data' }); + expect(data.device).to.nested.include({ 'ext.data': 'some device data' }); + expect(data.user).to.nested.include({ 'ext.data': 'some user data' }); + expect(data.regs).to.nested.include({ 'ext.data': 'some regs data' }); }); it('should accept tmax from global config if not set by requestBids method', function() { @@ -685,7 +685,7 @@ describe('ConnectAd Adapter', function () { describe('GPP Sync', function() { it('should concatenate gppString and applicableSections values in the returned image url', () => { const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5] }; - const result = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, undefined, undefined, undefined, gppConsent); + const result = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, undefined, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'image', url: `https://sync.connectad.io/ImageSyncer?gpp=DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN&gpp_sid=5&` @@ -694,7 +694,7 @@ describe('ConnectAd Adapter', function () { it('should concatenate gppString and applicableSections values in the returned iFrame url', () => { const gppConsent = { gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN', applicableSections: [5, 6] }; - const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + const result = spec.getUserSyncs({ iframeEnabled: true }, undefined, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `https://sync.connectad.io/iFrameSyncer?gpp=DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA~1YNN&gpp_sid=5%2C6&` @@ -702,7 +702,7 @@ describe('ConnectAd Adapter', function () { }); it('should return url without Gpp consent if gppConsent is undefined', () => { - const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, undefined); + const result = spec.getUserSyncs({ iframeEnabled: true }, undefined, undefined, undefined, undefined); expect(result).to.deep.equal([{ type: 'iframe', url: `https://sync.connectad.io/iFrameSyncer?` @@ -711,7 +711,7 @@ describe('ConnectAd Adapter', function () { it('should return iFrame url without Gpp consent if gppConsent.gppString is undefined', () => { const gppConsent = { applicableSections: ['5'] }; - const result = spec.getUserSyncs({iframeEnabled: true}, undefined, undefined, undefined, gppConsent); + const result = spec.getUserSyncs({ iframeEnabled: true }, undefined, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'iframe', url: `https://sync.connectad.io/iFrameSyncer?` @@ -731,7 +731,7 @@ describe('ConnectAd Adapter', function () { }, { name: 'iframe/gdpr', - arguments: [{ iframeEnabled: true, pixelEnabled: false }, {}, {gdprApplies: true, consentString: '234234'}], + arguments: [{ iframeEnabled: true, pixelEnabled: false }, {}, { gdprApplies: true, consentString: '234234' }], expect: { type: 'iframe', pixels: ['https://sync.connectad.io/iFrameSyncer?gdpr=1&gdpr_consent=234234&'] @@ -747,7 +747,7 @@ describe('ConnectAd Adapter', function () { }, { name: 'iframe/ccpa & gdpr', - arguments: [{ iframeEnabled: true, pixelEnabled: false }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], + arguments: [{ iframeEnabled: true, pixelEnabled: false }, {}, { gdprApplies: true, consentString: '234234' }, 'YN12'], expect: { type: 'iframe', pixels: ['https://sync.connectad.io/iFrameSyncer?gdpr=1&gdpr_consent=234234&us_privacy=YN12&'] @@ -755,7 +755,7 @@ describe('ConnectAd Adapter', function () { }, { name: 'image/ccpa & gdpr', - arguments: [{ iframeEnabled: false, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], + arguments: [{ iframeEnabled: false, pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }, 'YN12'], expect: { type: 'image', pixels: ['https://sync.connectad.io/ImageSyncer?gdpr=1&gdpr_consent=234234&us_privacy=YN12&'] @@ -763,7 +763,7 @@ describe('ConnectAd Adapter', function () { }, { name: 'image/gdpr', - arguments: [{ iframeEnabled: false, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], + arguments: [{ iframeEnabled: false, pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }], expect: { type: 'image', pixels: ['https://sync.connectad.io/ImageSyncer?gdpr=1&gdpr_consent=234234&'] diff --git a/test/spec/modules/consentManagementGpp_spec.js b/test/spec/modules/consentManagementGpp_spec.js index e143311a880..25fd87a65da 100644 --- a/test/spec/modules/consentManagementGpp_spec.js +++ b/test/spec/modules/consentManagementGpp_spec.js @@ -4,9 +4,9 @@ import { resetConsentData, setConsentConfig, } from 'modules/consentManagementGpp.js'; -import {gppDataHandler} from 'src/adapterManager.js'; +import { gppDataHandler } from 'src/adapterManager.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import 'src/prebid.js'; const expect = require('chai').expect; @@ -179,7 +179,7 @@ describe('consentManagementGpp', function () { let gppClient, gppData, eventListener; function mockClient(apiVersion = '1.1', cmpVersion = '1.1') { - const mockCmp = sinon.stub().callsFake(function ({command, callback}) { + const mockCmp = sinon.stub().callsFake(function ({ command, callback }) { if (command === 'addEventListener') { eventListener = callback; } else { @@ -253,7 +253,7 @@ describe('consentManagementGpp', function () { Object.entries(tests).forEach(([t, value]) => { describe(t, () => { it('should not update', (done) => { - Object.assign(gppData, {[prop]: value}); + Object.assign(gppData, { [prop]: value }); gppClient.updateConsent(gppData).catch(err => { expect(err.message).to.match(/unexpected/); expect(err.args).to.eql([gppData]); @@ -270,13 +270,13 @@ describe('consentManagementGpp', function () { describe('init', () => { it('does not use initial pingData if CMP is not ready', () => { - gppClient.init({...gppData, signalStatus: 'not ready'}); + gppClient.init({ ...gppData, signalStatus: 'not ready' }); expect(eventListener).to.exist; expect(gppDataHandler.ready).to.be.false; }); it('uses initial pingData (and resolves promise) if CMP is ready', () => { - return gppClient.init({...gppData, signalStatus: 'ready'}).then(data => { + return gppClient.init({ ...gppData, signalStatus: 'ready' }).then(data => { expect(eventListener).to.exist; sinon.assert.match(data, gppData); sinon.assert.match(gppDataHandler.getConsentData(), gppData); @@ -284,7 +284,7 @@ describe('consentManagementGpp', function () { }); it('rejects promise when CMP errors out', (done) => { - gppClient.init({signalStatus: 'not ready'}).catch((err) => { + gppClient.init({ signalStatus: 'not ready' }).catch((err) => { expect(err.message).to.match(/error/); expect(err.args).to.eql(['error']) done(); @@ -295,10 +295,10 @@ describe('consentManagementGpp', function () { Object.entries({ 'empty': {}, 'null': null, - 'irrelevant': {eventName: 'irrelevant'} + 'irrelevant': { eventName: 'irrelevant' } }).forEach(([t, evt]) => { it(`ignores ${t} events`, () => { - const pm = gppClient.init({signalStatus: 'not ready'}).catch((err) => err.args[0] !== 'done' && Promise.reject(err)); + const pm = gppClient.init({ signalStatus: 'not ready' }).catch((err) => err.args[0] !== 'done' && Promise.reject(err)); eventListener(evt); eventListener('done', false); return pm; @@ -306,8 +306,8 @@ describe('consentManagementGpp', function () { }); it('rejects the promise when cmpStatus is "error"', (done) => { - const evt = {eventName: 'other', pingData: {cmpStatus: 'error'}}; - gppClient.init({signalStatus: 'not ready'}).catch(err => { + const evt = { eventName: 'other', pingData: { cmpStatus: 'error' } }; + gppClient.init({ signalStatus: 'not ready' }).catch(err => { expect(err.message).to.match(/error/); expect(err.args).to.eql([evt]); done(); @@ -326,34 +326,34 @@ describe('consentManagementGpp', function () { let gppData2 beforeEach(() => { - gppData2 = Object.assign(gppData, {gppString: '2nd'}); + gppData2 = Object.assign(gppData, { gppString: '2nd' }); }); it('does not fire consent data updates if the CMP is not ready', (done) => { - gppClient.init({signalStatus: 'not ready'}).catch(() => { + gppClient.init({ signalStatus: 'not ready' }).catch(() => { expect(gppDataHandler.ready).to.be.false; done(); }); - eventListener({...gppData2, signalStatus: 'not ready'}); + eventListener({ ...gppData2, signalStatus: 'not ready' }); eventListener('done', false); }) it('fires consent data updates (and resolves promise) if CMP is ready', (done) => { - gppClient.init({signalStatus: 'not ready'}).then(data => { + gppClient.init({ signalStatus: 'not ready' }).then(data => { sinon.assert.match(data, gppData2); done() }); - eventListener(makeEvent({...gppData2, signalStatus: 'ready'})); + eventListener(makeEvent({ ...gppData2, signalStatus: 'ready' })); }); it('keeps updating consent data on new events', () => { - const pm = gppClient.init({signalStatus: 'not ready'}).then(data => { + const pm = gppClient.init({ signalStatus: 'not ready' }).then(data => { sinon.assert.match(data, gppData); sinon.assert.match(gppDataHandler.getConsentData(), gppData); }); - eventListener(makeEvent({...gppData, signalStatus: 'ready'})); + eventListener(makeEvent({ ...gppData, signalStatus: 'ready' })); return pm.then(() => { - eventListener(makeEvent({...gppData2, signalStatus: 'ready'})) + eventListener(makeEvent({ ...gppData2, signalStatus: 'ready' })) }).then(() => { sinon.assert.match(gppDataHandler.getConsentData(), gppData2); }); @@ -377,7 +377,7 @@ describe('consentManagementGpp', function () { 'undefined': [false, undefined] }).forEach(([t, [expected, signalStatus]]) => { it(`should be ${expected} when signalStatus is ${t}`, () => { - expect(gppClient.isCMPReady(Object.assign({}, {signalStatus}))).to.equal(expected); + expect(gppClient.isCMPReady(Object.assign({}, { signalStatus }))).to.equal(expected); }); }); }); @@ -498,7 +498,7 @@ describe('consentManagementGpp', function () { window.__gpp = sinon.stub().callsFake(function (command, callback) { switch (command) { case 'addEventListener': - triggerCMPEvent = (event, payload = {}) => callback({eventName: event, pingData: {...pingData, ...payload}}) + triggerCMPEvent = (event, payload = {}) => callback({ eventName: event, pingData: { ...pingData, ...payload } }) break; case 'ping': callback(pingData) @@ -526,9 +526,9 @@ describe('consentManagementGpp', function () { it('should wait for signalStatus: ready', async () => { const didHookRun = startHook(); expect(await didHookRun()).to.be.false; - triggerCMPEvent('sectionChange', {signalStatus: 'not ready'}); + triggerCMPEvent('sectionChange', { signalStatus: 'not ready' }); expect(await didHookRun()).to.be.false; - triggerCMPEvent('sectionChange', {signalStatus: 'ready'}); + triggerCMPEvent('sectionChange', { signalStatus: 'ready' }); await consentConfig.loadConsentData(); expect(await didHookRun()).to.be.true; expect(gppDataHandler.getConsentData().gppString).to.eql('xyz'); @@ -537,7 +537,7 @@ describe('consentManagementGpp', function () { it('should re-use GPP data once ready', async () => { let didHookRun = startHook(); await didHookRun(); - triggerCMPEvent('sectionChange', {signalStatus: 'ready'}); + triggerCMPEvent('sectionChange', { signalStatus: 'ready' }); await consentConfig.loadConsentData(); window.__gpp.resetHistory(); didHookRun = startHook(); @@ -549,13 +549,13 @@ describe('consentManagementGpp', function () { it('after signalStatus: ready, should wait again for signalStatus: ready', async () => { let didHookRun = startHook(); await didHookRun(); - triggerCMPEvent('sectionChange', {signalStatus: 'ready'}); + triggerCMPEvent('sectionChange', { signalStatus: 'ready' }); await consentConfig.loadConsentData(); for (const run of ['first', 'second']) { - triggerCMPEvent('cmpDisplayStatus', {signalStatus: 'not ready'}); + triggerCMPEvent('cmpDisplayStatus', { signalStatus: 'not ready' }); didHookRun = startHook(); expect(await didHookRun()).to.be.false; - triggerCMPEvent('sectionChange', {signalStatus: 'ready', gppString: run}); + triggerCMPEvent('sectionChange', { signalStatus: 'ready', gppString: run }); await consentConfig.loadConsentData(); expect(await didHookRun()).to.be.true; expect(gppDataHandler.getConsentData().gppString).to.eql(run); diff --git a/test/spec/modules/consentManagementUsp_spec.js b/test/spec/modules/consentManagementUsp_spec.js index 8b011f20cbb..f9cfa19ed62 100644 --- a/test/spec/modules/consentManagementUsp_spec.js +++ b/test/spec/modules/consentManagementUsp_spec.js @@ -8,9 +8,9 @@ import { } from 'modules/consentManagementUsp.js'; import * as utils from 'src/utils.js'; import { config } from 'src/config.js'; -import adapterManager, {gdprDataHandler, uspDataHandler} from 'src/adapterManager.js'; -import {requestBids} from '../../../src/prebid.js'; -import {defer} from '../../../src/utils/promise.js'; +import adapterManager, { gdprDataHandler, uspDataHandler } from 'src/adapterManager.js'; +import { requestBids } from '../../../src/prebid.js'; +import { defer } from '../../../src/utils/promise.js'; const expect = require('chai').expect; @@ -79,7 +79,7 @@ describe('consentManagement', function () { }); it('should use system default values', function () { - setConsentConfig({usp: {}}); + setConsentConfig({ usp: {} }); expect(consentAPI).to.be.equal('iab'); expect(consentTimeout).to.be.equal(50); sinon.assert.callCount(utils.logInfo, 3); @@ -113,7 +113,7 @@ describe('consentManagement', function () { }); it('should immediately start looking up consent data', () => { - setConsentConfig({usp: {cmpApi: 'invalid'}}); + setConsentConfig({ usp: { cmpApi: 'invalid' } }); expect(uspDataHandler.ready).to.be.true; }); }); @@ -138,12 +138,12 @@ describe('consentManagement', function () { }); it('should enable uspDataHandler', () => { - setConsentConfig({usp: {cmpApi: 'daa', timeout: 7500}}); + setConsentConfig({ usp: { cmpApi: 'daa', timeout: 7500 } }); expect(uspDataHandler.enabled).to.be.true; }); it('should call setConsentData(null) on invalid CMP api', () => { - setConsentConfig({usp: {cmpApi: 'invalid'}}); + setConsentConfig({ usp: { cmpApi: 'invalid' } }); let hookRan = false; requestBidsHook(() => { hookRan = true; @@ -296,7 +296,7 @@ describe('consentManagement', function () { }); it('should call uspDataHandler.setConsentData(null) on timeout', (done) => { - setConsentConfig({usp: {timeout: 10}}); + setConsentConfig({ usp: { timeout: 10 } }); let hookRan = false; uspStub = sinon.stub(window, '__uspapi').callsFake(() => {}); requestBidsHook(() => { hookRan = true; }, {}); @@ -338,7 +338,7 @@ describe('consentManagement', function () { if (event && event.data) { const data = event.data; if (data.__uspapiCall) { - const {command, version, callId} = data.__uspapiCall; + const { command, version, callId } = data.__uspapiCall; let response = mockApi(command, version, callId); if (response) { response = { @@ -515,7 +515,7 @@ describe('consentManagement', function () { if (cmd === 'registerDeletion') { throw new Error('CMP not compliant'); } else if (cmd === 'getUSPData') { - cb({uspString: 'string'}, true); + cb({ uspString: 'string' }, true); } }); setConsentConfig(goodConfig); @@ -527,7 +527,7 @@ describe('consentManagement', function () { if (cmd === 'registerDeletion') { cb(null, false); } else { - cb({uspString: 'string'}, true); + cb({ uspString: 'string' }, true); } }); setConsentConfig(goodConfig); diff --git a/test/spec/modules/consentManagement_spec.js b/test/spec/modules/consentManagement_spec.js index dfe5f3d6a0e..8e6d08b9605 100644 --- a/test/spec/modules/consentManagement_spec.js +++ b/test/spec/modules/consentManagement_spec.js @@ -1,7 +1,7 @@ -import {consentConfig, gdprScope, resetConsentData, setConsentConfig, tcfCmpEventManager} from 'modules/consentManagementTcf.js'; -import {gdprDataHandler} from 'src/adapterManager.js'; +import { consentConfig, gdprScope, resetConsentData, setConsentConfig, tcfCmpEventManager } from 'modules/consentManagementTcf.js'; +import { gdprDataHandler } from 'src/adapterManager.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import 'src/prebid.js'; const expect = require('chai').expect; @@ -9,7 +9,7 @@ const expect = require('chai').expect; describe('consentManagement', function () { function mockCMP(cmpResponse) { return function(...args) { - args[2](Object.assign({eventStatus: 'tcloaded'}, cmpResponse), true); + args[2](Object.assign({ eventStatus: 'tcloaded' }, cmpResponse), true); } } @@ -41,7 +41,7 @@ describe('consentManagement', function () { }); it('should exit consent manager if gdpr not set with new config structure', async function () { - await setConsentConfig({usp: {cmpApi: 'iab', timeout: 50}}); + await setConsentConfig({ usp: { cmpApi: 'iab', timeout: 50 } }); expect(consentConfig.cmpHandler).to.be.undefined; sinon.assert.calledOnce(utils.logWarn); }); @@ -60,7 +60,7 @@ describe('consentManagement', function () { }) it('should immediately look up consent data', async () => { - await setConsentConfig({gdpr: {cmpApi: 'invalid'}}); + await setConsentConfig({ gdpr: { cmpApi: 'invalid' } }); expect(gdprDataHandler.ready).to.be.true; }) }); @@ -85,7 +85,7 @@ describe('consentManagement', function () { it('should use new consent manager config structure for gdpr', async function () { await setConsentConfig({ - gdpr: {cmpApi: 'daa', timeout: 8700} + gdpr: { cmpApi: 'daa', timeout: 8700 } }); expect(consentConfig.cmpHandler).to.be.equal('daa'); @@ -94,8 +94,8 @@ describe('consentManagement', function () { it('should ignore config.usp and use config.gdpr, with default cmpApi', async function () { await setConsentConfig({ - gdpr: {timeout: 5000}, - usp: {cmpApi: 'daa', timeout: 50} + gdpr: { timeout: 5000 }, + usp: { cmpApi: 'daa', timeout: 50 } }); expect(consentConfig.cmpHandler).to.be.equal('iab'); @@ -105,7 +105,7 @@ describe('consentManagement', function () { it('should ignore config.usp and use config.gdpr, with default cmpAip and timeout', async function () { await setConsentConfig({ gdpr: {}, - usp: {cmpApi: 'daa', timeout: 50} + usp: { cmpApi: 'daa', timeout: 50 } }); expect(consentConfig.cmpHandler).to.be.equal('iab'); @@ -134,14 +134,14 @@ describe('consentManagement', function () { }); it('should enable gdprDataHandler', async () => { - await setConsentConfig({gdpr: {}}); + await setConsentConfig({ gdpr: {} }); expect(gdprDataHandler.enabled).to.be.true; }); }); describe('static consent string setConsentConfig value', () => { Object.entries({ - 'getTCData': (cfg) => ({getTCData: cfg}), + 'getTCData': (cfg) => ({ getTCData: cfg }), 'consent data directly': (cfg) => cfg, }).forEach(([t, packageCfg]) => { describe(`using ${t}`, () => { @@ -284,7 +284,7 @@ describe('consentManagement', function () { }); it('should call gdprDataHandler.setConsentData() when unknown CMP api is used', async () => { - await setConsentConfig({gdpr: {cmpApi: 'invalid'}}); + await setConsentConfig({ gdpr: { cmpApi: 'invalid' } }); expect(await runHook()).to.be.true; expect(gdprDataHandler.ready).to.be.true; }) @@ -319,7 +319,7 @@ describe('consentManagement', function () { it('should not trip when adUnits have no size', async () => { await setConsentConfig(staticConfig); - expect(await runHook({adUnits: [{code: 'test', mediaTypes: {video: {}}}]})).to.be.true; + expect(await runHook({ adUnits: [{ code: 'test', mediaTypes: { video: {} } }] })).to.be.true; }); it('should continue the auction immediately, without consent data, if timeout is 0', async () => { @@ -585,7 +585,7 @@ describe('consentManagement', function () { [utils.logWarn, utils.logError].forEach((stub) => stub.resetHistory()); - expect(await runHook({bidsBackHandler: () => bidsBackHandlerReturn = true})).to.be.false; + expect(await runHook({ bidsBackHandler: () => bidsBackHandlerReturn = true })).to.be.false; const consent = gdprDataHandler.getConsentData(); sinon.assert.calledOnce(utils.logError); @@ -701,7 +701,7 @@ describe('consentManagement', function () { mockTcfEvent({ eventStatus: 'cmpuishown', tcString: cs, - vendorData: {random: 'junk'} + vendorData: { random: 'junk' } }); return runAuction().then(() => { const consent = gdprDataHandler.getConsentData(); diff --git a/test/spec/modules/consumableBidAdapter_spec.js b/test/spec/modules/consumableBidAdapter_spec.js index 51db64019b5..c60a0abebd0 100644 --- a/test/spec/modules/consumableBidAdapter_spec.js +++ b/test/spec/modules/consumableBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/consumableBidAdapter.js'; -import {createBid} from 'src/bidfactory.js'; -import {config} from 'src/config.js'; -import {deepClone} from 'src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/consumableBidAdapter.js'; +import { createBid } from 'src/bidfactory.js'; +import { config } from 'src/config.js'; +import { deepClone } from 'src/utils.js'; import { createEidsArray } from 'modules/userId/eids.js'; const ENDPOINT = 'https://e.serverbid.com/api/v2'; @@ -242,7 +242,7 @@ const AD_SERVER_RESPONSE = { 'height': 90, 'width': 728, 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} + 'pricing': { 'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5 } }, '123': { 'adId': 2364764, @@ -265,7 +265,7 @@ const AD_SERVER_RESPONSE = { 'height': 90, 'width': 728, 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5} + 'pricing': { 'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5 } } } } @@ -299,7 +299,7 @@ const AD_SERVER_RESPONSE_2 = { 'height': 90, 'width': 728, 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5}, + 'pricing': { 'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5 }, 'mediaType': 'banner', 'cats': ['IAB1', 'IAB2', 'IAB3'], 'networkId': 1234567, @@ -325,7 +325,7 @@ const AD_SERVER_RESPONSE_2 = { 'height': 90, 'width': 728, 'events': [], - 'pricing': {'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5}, + 'pricing': { 'price': 0.5, 'clearPrice': 0.5, 'revenue': 0.0005, 'rateType': 2, 'eCPM': 0.5 }, 'mediaType': 'banner', 'cats': ['IAB1', 'IAB2'], 'networkId': 2345678, @@ -614,7 +614,7 @@ describe('Consumable BidAdapter', function () { }) it('handles nobid responses', function () { - const EMPTY_RESP = Object.assign({}, AD_SERVER_RESPONSE, {'body': {'decisions': null}}) + const EMPTY_RESP = Object.assign({}, AD_SERVER_RESPONSE, { 'body': { 'decisions': null } }) const bids = spec.interpretResponse(EMPTY_RESP, BUILD_REQUESTS_OUTPUT); expect(bids).to.be.empty; @@ -627,7 +627,7 @@ describe('Consumable BidAdapter', function () { }); }); describe('getUserSyncs', function () { - const syncOptions = {'iframeEnabled': true}; + const syncOptions = { 'iframeEnabled': true }; it('handles empty sync options', function () { const opts = spec.getUserSyncs({}); @@ -724,7 +724,7 @@ describe('Consumable BidAdapter', function () { }) it('should return a sync url if pixel syncs are enabled and some are returned from the server', function () { - const syncOptions = {'pixelEnabled': true}; + const syncOptions = { 'pixelEnabled': true }; const opts = spec.getUserSyncs(syncOptions, [AD_SERVER_RESPONSE]); expect(opts.length).to.equal(1); diff --git a/test/spec/modules/contentexchangeBidAdapter_spec.js b/test/spec/modules/contentexchangeBidAdapter_spec.js index 12a4c6c5de2..cdf5be50250 100644 --- a/test/spec/modules/contentexchangeBidAdapter_spec.js +++ b/test/spec/modules/contentexchangeBidAdapter_spec.js @@ -481,7 +481,7 @@ describe('ContentexchangeBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -490,9 +490,7 @@ describe('ContentexchangeBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync2.adnetwork.agency/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -501,7 +499,7 @@ describe('ContentexchangeBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync2.adnetwork.agency/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/conversantBidAdapter_spec.js b/test/spec/modules/conversantBidAdapter_spec.js index ac19bcd10d3..209e660d0bd 100644 --- a/test/spec/modules/conversantBidAdapter_spec.js +++ b/test/spec/modules/conversantBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/conversantBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/conversantBidAdapter.js'; import * as utils from 'src/utils.js'; -import {deepAccess} from 'src/utils'; +import { deepAccess } from 'src/utils'; // load modules that register ORTB processors import 'src/prebid.js' import 'modules/currency.js'; @@ -9,8 +9,8 @@ import 'modules/userId/index.js'; // handles eids import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import {hook} from '../../../src/hook.js' -import {BANNER} from '../../../src/mediaTypes.js'; +import { hook } from '../../../src/hook.js' +import { BANNER } from '../../../src/mediaTypes.js'; describe('Conversant adapter tests', function() { const siteId = '108060'; @@ -233,8 +233,8 @@ describe('Conversant adapter tests', function() { it('Verify isBidRequestValid', function() { expect(spec.isBidRequestValid({})).to.be.false; - expect(spec.isBidRequestValid({params: {}})).to.be.false; - expect(spec.isBidRequestValid({params: {site_id: '123'}})).to.be.true; + expect(spec.isBidRequestValid({ params: {} })).to.be.false; + expect(spec.isBidRequestValid({ params: { site_id: '123' } })).to.be.true; bidRequests.forEach((bid) => { expect(spec.isBidRequestValid(bid)).to.be.true; }); @@ -316,7 +316,7 @@ describe('Conversant adapter tests', function() { expect(payload.imp[0]).to.have.property('banner'); expect(payload.imp[0].banner).to.have.property('pos', 1); expect(payload.imp[0].banner).to.have.property('format'); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }]); expect(payload.imp[0]).to.not.have.property('video'); }); @@ -330,7 +330,7 @@ describe('Conversant adapter tests', function() { expect(payload.imp[1]).to.have.property('banner'); expect(payload.imp[1].banner).to.not.have.property('pos'); expect(payload.imp[1].banner).to.have.property('format'); - expect(payload.imp[1].banner.format).to.deep.equal([{w: 728, h: 90}, {w: 468, h: 60}]); + expect(payload.imp[1].banner.format).to.deep.equal([{ w: 728, h: 90 }, { w: 468, h: 60 }]); }); it('Banner with tagid and position', () => { @@ -342,7 +342,7 @@ describe('Conversant adapter tests', function() { expect(payload.imp[2]).to.have.property('banner'); expect(payload.imp[2].banner).to.have.property('pos', 2); expect(payload.imp[2].banner).to.have.property('format'); - expect(payload.imp[2].banner.format).to.deep.equal([{w: 300, h: 600}, {w: 160, h: 600}]); + expect(payload.imp[2].banner.format).to.deep.equal([{ w: 300, h: 600 }, { w: 160, h: 600 }]); }); if (FEATURES.VIDEO) { @@ -427,8 +427,8 @@ describe('Conversant adapter tests', function() { it('Verify first party data', () => { const bidderRequest = { - refererInfo: {page: 'http://test.com?a=b&c=123'}, - ortb2: {site: {content: {series: 'MySeries', season: 'MySeason', episode: 3, title: 'MyTitle'}}} + refererInfo: { page: 'http://test.com?a=b&c=123' }, + ortb2: { site: { content: { series: 'MySeries', season: 'MySeason', episode: 3, title: 'MyTitle' } } } }; const request = spec.buildRequests(bidRequests, bidderRequest); const payload = request.data; @@ -440,20 +440,20 @@ describe('Conversant adapter tests', function() { }); it('Verify currency', () => { - const bidderRequest = { timeout: 9999, ortb2: {cur: ['EUR']} }; + const bidderRequest = { timeout: 9999, ortb2: { cur: ['EUR'] } }; const request = spec.buildRequests(bidRequests, bidderRequest); const payload = request.data; expect(payload.cur).deep.equal(['USD']); }) it('Verify supply chain data', () => { - const bidderRequest = {refererInfo: {page: 'http://test.com?a=b&c=123'}}; - const schain = {complete: 1, ver: '1.0', nodes: [{asi: 'bidderA.com', sid: '00001', hp: 1}]}; + const bidderRequest = { refererInfo: { page: 'http://test.com?a=b&c=123' } }; + const schain = { complete: 1, ver: '1.0', nodes: [{ asi: 'bidderA.com', sid: '00001', hp: 1 }] }; // Add schain to bidderRequest bidderRequest.ortb2 = { source: { - ext: {schain: schain} + ext: { schain: schain } } }; @@ -461,7 +461,7 @@ describe('Conversant adapter tests', function() { return Object.assign({ ortb2: { source: { - ext: {schain: schain} + ext: { schain: schain } } } }, bid); @@ -474,7 +474,7 @@ describe('Conversant adapter tests', function() { it('Verify override url', function() { const testUrl = 'https://someurl?name=value'; - const request = spec.buildRequests([{params: {white_label_url: testUrl}}], {}); + const request = spec.buildRequests([{ params: { white_label_url: testUrl } }], {}); expect(request.url).to.equal(testUrl); }); @@ -564,10 +564,11 @@ describe('Conversant adapter tests', function() { const nativeMarkup = JSON.stringify({ native: { assets: [ - {id: 1, title: {text: 'TextValue!'}}, - {id: 5, data: {value: 'Epsilon'}}, + { id: 1, title: { text: 'TextValue!' } }, + { id: 5, data: { value: 'Epsilon' } }, ], - link: { url: 'https://www.epsilon.com/us', }, } + link: { url: 'https://www.epsilon.com/us', }, + } }); const nativeBidResponse = { @@ -607,13 +608,13 @@ describe('Conversant adapter tests', function() { // clone bidRequests const requests = utils.deepClone(bidRequests); - const eidArray = [{'source': 'pubcid.org', 'uids': [{'id': '112233', 'atype': 1}]}, {'source': 'liveramp.com', 'uids': [{'id': '334455', 'atype': 3}]}]; + const eidArray = [{ 'source': 'pubcid.org', 'uids': [{ 'id': '112233', 'atype': 1 }] }, { 'source': 'liveramp.com', 'uids': [{ 'id': '334455', 'atype': 3 }] }]; // construct http post payload - const payload = spec.buildRequests(requests, {ortb2: {user: {ext: {eids: eidArray}}}}).data; + const payload = spec.buildRequests(requests, { ortb2: { user: { ext: { eids: eidArray } } } }).data; expect(payload).to.have.deep.nested.property('user.ext.eids', [ - {source: 'pubcid.org', uids: [{id: '112233', atype: 1}]}, - {source: 'liveramp.com', uids: [{id: '334455', atype: 3}]} + { source: 'pubcid.org', uids: [{ id: '112233', atype: 1 }] }, + { source: 'liveramp.com', uids: [{ id: '334455', atype: 3 }] } ]); }); }); @@ -694,7 +695,7 @@ describe('Conversant adapter tests', function() { describe('getUserSyncs', function() { const syncurl_iframe = 'https://sync.dotomi.com:8080/iframe'; const syncurl_image = 'https://sync.dotomi.com:8080/pixel'; - const cnvrResponse = {ext: {psyncs: [syncurl_image], fsyncs: [syncurl_iframe]}}; + const cnvrResponse = { ext: { psyncs: [syncurl_image], fsyncs: [syncurl_iframe] } }; let sandbox; beforeEach(function () { sandbox = sinon.createSandbox(); @@ -706,43 +707,43 @@ describe('Conversant adapter tests', function() { it('empty params', function() { expect(spec.getUserSyncs({ iframeEnabled: true }, [], undefined, undefined)) .to.deep.equal([]); - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: {ext: {}}}], undefined, undefined)) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: { ext: {} } }], undefined, undefined)) .to.deep.equal([]); - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: cnvrResponse}], undefined, undefined)) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: cnvrResponse }], undefined, undefined)) .to.deep.equal([{ type: 'iframe', url: syncurl_iframe }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: cnvrResponse}], undefined, undefined)) + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: cnvrResponse }], undefined, undefined)) .to.deep.equal([{ type: 'image', url: syncurl_image }]); - expect(spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [{body: cnvrResponse}], undefined, undefined)) - .to.deep.equal([{type: 'iframe', url: syncurl_iframe}, {type: 'image', url: syncurl_image}]); + expect(spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, [{ body: cnvrResponse }], undefined, undefined)) + .to.deep.equal([{ type: 'iframe', url: syncurl_iframe }, { type: 'image', url: syncurl_image }]); }); it('URL building', function() { - expect(spec.getUserSyncs({pixelEnabled: true}, [{body: {ext: {psyncs: [`${syncurl_image}?sid=1234`]}}}], undefined, undefined)) - .to.deep.equal([{type: 'image', url: `${syncurl_image}?sid=1234`}]); - expect(spec.getUserSyncs({pixelEnabled: true}, [{body: {ext: {psyncs: [`${syncurl_image}?sid=1234`]}}}], undefined, '1NYN')) - .to.deep.equal([{type: 'image', url: `${syncurl_image}?sid=1234&us_privacy=1NYN`}]); + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: { ext: { psyncs: [`${syncurl_image}?sid=1234`] } } }], undefined, undefined)) + .to.deep.equal([{ type: 'image', url: `${syncurl_image}?sid=1234` }]); + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: { ext: { psyncs: [`${syncurl_image}?sid=1234`] } } }], undefined, '1NYN')) + .to.deep.equal([{ type: 'image', url: `${syncurl_image}?sid=1234&us_privacy=1NYN` }]); }); it('GDPR', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: cnvrResponse}], {gdprApplies: true, consentString: 'consentstring'}, undefined)) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: true, consentString: 'consentstring' }, undefined)) .to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}?gdpr=1&gdpr_consent=consentstring` }]); - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: cnvrResponse}], {gdprApplies: false, consentString: 'consentstring'}, undefined)) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: false, consentString: 'consentstring' }, undefined)) .to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}?gdpr=0&gdpr_consent=consentstring` }]); - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: cnvrResponse}], {gdprApplies: true, consentString: undefined}, undefined)) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: true, consentString: undefined }, undefined)) .to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}?gdpr=1&gdpr_consent=` }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: cnvrResponse}], {gdprApplies: true, consentString: 'consentstring'}, undefined)) + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: true, consentString: 'consentstring' }, undefined)) .to.deep.equal([{ type: 'image', url: `${syncurl_image}?gdpr=1&gdpr_consent=consentstring` }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: cnvrResponse}], {gdprApplies: false, consentString: 'consentstring'}, undefined)) + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: false, consentString: 'consentstring' }, undefined)) .to.deep.equal([{ type: 'image', url: `${syncurl_image}?gdpr=0&gdpr_consent=consentstring` }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: cnvrResponse}], {gdprApplies: true, consentString: undefined}, undefined)) + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: cnvrResponse }], { gdprApplies: true, consentString: undefined }, undefined)) .to.deep.equal([{ type: 'image', url: `${syncurl_image}?gdpr=1&gdpr_consent=` }]); }); it('US_Privacy', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, [{body: cnvrResponse}], undefined, '1NYN')) + expect(spec.getUserSyncs({ iframeEnabled: true }, [{ body: cnvrResponse }], undefined, '1NYN')) .to.deep.equal([{ type: 'iframe', url: `${syncurl_iframe}?us_privacy=1NYN` }]); - expect(spec.getUserSyncs({ pixelEnabled: true }, [{body: cnvrResponse}], undefined, '1NYN')) + expect(spec.getUserSyncs({ pixelEnabled: true }, [{ body: cnvrResponse }], undefined, '1NYN')) .to.deep.equal([{ type: 'image', url: `${syncurl_image}?us_privacy=1NYN` }]); }); }); diff --git a/test/spec/modules/copper6sspBidAdapter_spec.js b/test/spec/modules/copper6sspBidAdapter_spec.js index 3c32750cbc0..888291c5997 100644 --- a/test/spec/modules/copper6sspBidAdapter_spec.js +++ b/test/spec/modules/copper6sspBidAdapter_spec.js @@ -484,7 +484,7 @@ describe('Copper6SSPBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -493,9 +493,7 @@ describe('Copper6SSPBidAdapter', function () { expect(syncData[0].url).to.equal('https://сsync.copper6.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -504,7 +502,7 @@ describe('Copper6SSPBidAdapter', function () { expect(syncData[0].url).to.equal('https://сsync.copper6.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/craftBidAdapter_spec.js b/test/spec/modules/craftBidAdapter_spec.js index 45922e1cc25..963662653e3 100644 --- a/test/spec/modules/craftBidAdapter_spec.js +++ b/test/spec/modules/craftBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/craftBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { expect } from 'chai'; +import { spec } from 'modules/craftBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('craftAdapter', function () { const adapter = newBidder(spec); @@ -101,8 +101,8 @@ describe('craftAdapter', function () { }, }, userIdAsEids: [ - {source: 'foobar1.com', uids: [{id: 'xxxxxxx', atype: 1}]}, - {source: 'foobar2.com', uids: [{id: 'yyyyyyy', atype: 1}]}, + { source: 'foobar1.com', uids: [{ id: 'xxxxxxx', atype: 1 }] }, + { source: 'foobar2.com', uids: [{ id: 'yyyyyyy', atype: 1 }] }, ], }]; const bidderRequest = { @@ -134,8 +134,8 @@ describe('craftAdapter', function () { }); expect(data.user).to.deep.equals({ eids: [ - {source: 'foobar1.com', uids: [{id: 'xxxxxxx', atype: 1}]}, - {source: 'foobar2.com', uids: [{id: 'yyyyyyy', atype: 1}]}, + { source: 'foobar1.com', uids: [{ id: 'xxxxxxx', atype: 1 }] }, + { source: 'foobar2.com', uids: [{ id: 'yyyyyyy', atype: 1 }] }, ] }); }); @@ -172,7 +172,7 @@ describe('craftAdapter', function () { }] }; it('should get correct bid response', function() { - const bids = spec.interpretResponse(serverResponse, {bidderRequest: bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest: bidderRequest }); expect(bids).to.have.lengthOf(1); expect(bids[0]).to.deep.equals({ _adUnitCode: 'craft-prebid-example', diff --git a/test/spec/modules/criteoBidAdapter_spec.js b/test/spec/modules/criteoBidAdapter_spec.js index f6f6d31fe72..3d04b0f833c 100644 --- a/test/spec/modules/criteoBidAdapter_spec.js +++ b/test/spec/modules/criteoBidAdapter_spec.js @@ -1,18 +1,18 @@ -import {expect} from 'chai'; -import {spec, storage} from 'modules/criteoBidAdapter.js'; +import { expect } from 'chai'; +import { spec, storage } from 'modules/criteoBidAdapter.js'; import * as utils from 'src/utils.js'; import * as refererDetection from 'src/refererDetection.js'; import * as ajax from 'src/ajax.js'; -import {config} from '../../../src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; +import { config } from '../../../src/config.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; import 'modules/userId/index.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/consentManagementGpp.js'; -import {hook} from '../../../src/hook.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { hook } from '../../../src/hook.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('The Criteo bidding adapter', function () { let sandbox, ajaxStub, logWarnStub; @@ -80,7 +80,7 @@ describe('The Criteo bidding adapter', function () { const gppConsent = { gppString: 'gpp_string', - applicableSections: [ 1, 2 ] + applicableSections: [1, 2] }; const gdprConsent = { @@ -1182,7 +1182,7 @@ describe('The Criteo bidding adapter', function () { } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.regs.ext.gpp).to.equal('gpp_consent_string'); expect(ortbRequest.regs.ext.gpp_sid).to.deep.equal([0, 1, 2]); }); @@ -1222,7 +1222,7 @@ describe('The Criteo bidding adapter', function () { } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.regs.ext.dsa).to.deep.equal(dsa); }); @@ -1235,7 +1235,7 @@ describe('The Criteo bidding adapter', function () { bidder: 'criteo', ortb2: { source: { - ext: {schain: expectedSchain} + ext: { schain: expectedSchain } } }, adUnitCode: 'bid-123', @@ -1255,7 +1255,7 @@ describe('The Criteo bidding adapter', function () { ...bidderRequest, ortb2: { source: { - ext: {schain: expectedSchain} + ext: { schain: expectedSchain } } } }; @@ -1547,8 +1547,8 @@ describe('The Criteo bidding adapter', function () { segtax: 3 }, segment: [ - {'id': '1001'}, - {'id': '1002'} + { 'id': '1001' }, + { 'id': '1002' } ] }] }, @@ -1566,8 +1566,8 @@ describe('The Criteo bidding adapter', function () { segtax: 3 }, segment: [ - {'id': '1001'}, - {'id': '1002'} + { 'id': '1001' }, + { 'id': '1002' } ] }], ext: { @@ -1606,13 +1606,13 @@ describe('The Criteo bidding adapter', function () { user: userData }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; - expect(ortbRequest.user).to.deep.equal({...userData, ext: {...userData.ext, consent: 'consentDataString'}}); + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; + expect(ortbRequest.user).to.deep.equal({ ...userData, ext: { ...userData.ext, consent: 'consentDataString' } }); expect(ortbRequest.site).to.deep.equal({ ...siteData, page: refererUrl, domain: 'criteo.com', - publisher: {...ortbRequest.site.publisher, domain: 'criteo.com'} + publisher: { ...ortbRequest.site.publisher, domain: 'criteo.com' } }); expect(ortbRequest.imp[0].ext.bidfloor).to.equal(0.75); expect(ortbRequest.imp[0].ext.data.someContextAttribute).to.equal('abc') @@ -1621,7 +1621,7 @@ describe('The Criteo bidding adapter', function () { it('should properly build a request when coppa flag is true', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.regs.coppa).to.equal(1); }); @@ -1629,7 +1629,7 @@ describe('The Criteo bidding adapter', function () { it('should properly build a request when coppa flag is false', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: false}); + config.setConfig({ coppa: false }); const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.regs.coppa).to.equal(0); }); @@ -1676,8 +1676,8 @@ describe('The Criteo bidding adapter', function () { const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.imp[0].ext.floors).to.deep.equal({ 'banner': { - '300x250': {'currency': 'USD', 'floor': 1}, - '728x90': {'currency': 'USD', 'floor': 2} + '300x250': { 'currency': 'USD', 'floor': 1 }, + '728x90': { 'currency': 'USD', 'floor': 2 } } }); }); @@ -1703,8 +1703,8 @@ describe('The Criteo bidding adapter', function () { const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.imp[0].ext.floors).to.deep.equal({ 'banner': { - '300x250': {'currency': 'EUR', 'floor': 1}, - '728x90': {'currency': 'EUR', 'floor': 1} + '300x250': { 'currency': 'EUR', 'floor': 1 }, + '728x90': { 'currency': 'EUR', 'floor': 1 } } }); }); @@ -1744,8 +1744,8 @@ describe('The Criteo bidding adapter', function () { const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.imp[0].ext.floors).to.deep.equal({ 'video': { - '300x250': {'currency': 'USD', 'floor': 1}, - '728x90': {'currency': 'USD', 'floor': 2} + '300x250': { 'currency': 'USD', 'floor': 1 }, + '728x90': { 'currency': 'USD', 'floor': 2 } } }); }); @@ -1811,14 +1811,14 @@ describe('The Criteo bidding adapter', function () { expect(ortbRequest.imp[0].ext.data.someContextAttribute).to.deep.equal('abc'); expect(ortbRequest.imp[0].ext.floors).to.deep.equal({ 'banner': { - '300x250': {'currency': 'USD', 'floor': 1}, - '728x90': {'currency': 'USD', 'floor': 2} + '300x250': { 'currency': 'USD', 'floor': 1 }, + '728x90': { 'currency': 'USD', 'floor': 2 } }, 'video': { - '640x480': {'currency': 'EUR', 'floor': 3.2} + '640x480': { 'currency': 'EUR', 'floor': 3.2 } }, 'native': { - '*': {'currency': 'YEN', 'floor': 4.99} + '*': { 'currency': 'YEN', 'floor': 4.99 } } }); }); @@ -2008,21 +2008,21 @@ describe('The Criteo bidding adapter', function () { }); it('should interpret correctly gzip configuration given as a string', async function() { - bidderConfigStub.returns({criteo: {gzipEnabled: 'false'}}); + bidderConfigStub.returns({ criteo: { gzipEnabled: 'false' } }); const request = spec.buildRequests(defaultBidRequests, await addFPDToBidderRequest(bidderRequest)); expect(request.options.endpointCompression).to.be.false; }); it('should interpret correctly gzip configuration given as a boolean', async function () { - bidderConfigStub.returns({criteo: {gzipEnabled: false}}); + bidderConfigStub.returns({ criteo: { gzipEnabled: false } }); const request = spec.buildRequests(defaultBidRequests, await addFPDToBidderRequest(bidderRequest)); expect(request.options.endpointCompression).to.be.false; }); it('should default to true when it receives an invalid configuration', async function () { - bidderConfigStub.returns({criteo: {gzipEnabled: 'randomString'}}); + bidderConfigStub.returns({ criteo: { gzipEnabled: 'randomString' } }); const request = spec.buildRequests(defaultBidRequests, await addFPDToBidderRequest(bidderRequest)); expect(request.options.endpointCompression).to.be.true; @@ -2178,9 +2178,9 @@ describe('The Criteo bidding adapter', function () { it('should return an empty array when parsing a well-formed no bid response', async function () { const bidRequests = []; - const response = {seatbid: []}; + const response = { seatbid: [] }; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(0); }); @@ -2199,7 +2199,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', BANNER); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(BANNER); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2237,7 +2237,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', VIDEO); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2273,7 +2273,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', VIDEO); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2302,7 +2302,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', NATIVE); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(NATIVE); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2353,7 +2353,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId2', BANNER); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(BANNER); expect(bids[0].requestId).to.equal('test-bidId2'); @@ -2402,7 +2402,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', VIDEO); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2442,7 +2442,7 @@ describe('The Criteo bidding adapter', function () { }]; const response = mockResponse('test-bidId', NATIVE); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(NATIVE); expect(bids[0].requestId).to.equal('test-bidId'); @@ -2593,7 +2593,7 @@ describe('The Criteo bidding adapter', function () { }, }; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const interpretedResponse = spec.interpretResponse({body: response}, request); + const interpretedResponse = spec.interpretResponse({ body: response }, request); expect(interpretedResponse).to.have.property('bids'); expect(interpretedResponse).to.have.property('paapi'); expect(interpretedResponse.bids).to.have.lengthOf(0); @@ -2670,7 +2670,7 @@ describe('The Criteo bidding adapter', function () { }; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); @@ -2839,7 +2839,7 @@ describe('The Criteo bidding adapter', function () { ]; for (const nativeParams of nativeParamsWithoutSendId) { - let transformedBidRequests = {...bidRequests}; + let transformedBidRequests = { ...bidRequests }; transformedBidRequests = [Object.assign(transformedBidRequests[0], nativeParams), Object.assign(transformedBidRequests[1], nativeParams)]; spec.buildRequests(transformedBidRequests, await addFPDToBidderRequest(bidderRequest)); } diff --git a/test/spec/modules/criteoIdSystem_spec.js b/test/spec/modules/criteoIdSystem_spec.js index 1472a224a11..b82b4d56cb1 100644 --- a/test/spec/modules/criteoIdSystem_spec.js +++ b/test/spec/modules/criteoIdSystem_spec.js @@ -2,9 +2,9 @@ import { criteoIdSubmodule, storage } from 'modules/criteoIdSystem.js'; import * as utils from 'src/utils.js'; import { gdprDataHandler, uspDataHandler, gppDataHandler } from '../../../src/adapterManager.js'; import { server } from '../../mocks/xhr.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; const pastDateString = new Date(0).toString() @@ -373,7 +373,7 @@ describe('CriteoId module', function () { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'criteo.com', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); }) diff --git a/test/spec/modules/currency_spec.js b/test/spec/modules/currency_spec.js index 774e4617404..35b50eeb1bb 100644 --- a/test/spec/modules/currency_spec.js +++ b/test/spec/modules/currency_spec.js @@ -2,7 +2,7 @@ import { getCurrencyRates } from 'test/fixtures/fixtures.js'; -import {getGlobal} from 'src/prebidGlobal.js'; +import { getGlobal } from 'src/prebidGlobal.js'; import { setConfig, @@ -11,13 +11,13 @@ import { currencyRates, responseReady } from 'modules/currency.js'; -import {createBid} from '../../../src/bidfactory.js'; +import { createBid } from '../../../src/bidfactory.js'; import * as utils from 'src/utils.js'; -import {EVENTS, REJECTION_REASON} from '../../../src/constants.js'; -import {server} from '../../mocks/xhr.js'; +import { EVENTS, REJECTION_REASON } from '../../../src/constants.js'; +import { server } from '../../mocks/xhr.js'; import * as events from 'src/events.js'; import { enrichFPD } from '../../../src/fpd/enrichment.js'; -import {requestBidsHook} from '../../../modules/currency.js'; +import { requestBidsHook } from '../../../modules/currency.js'; var assert = require('chai').assert; var expect = require('chai').expect; @@ -90,7 +90,8 @@ describe('currency', function () { 'defaultRates': { 'GBP': { 'CNY': 66, 'JPY': 132, 'USD': 264 }, 'USD': { 'CNY': 60, 'GBP': 120, 'JPY': 240 } - } }); + } + }); fakeCurrencyFileServer.respond(); expect(fakeCurrencyFileServer.requests.length).to.equal(2); expect(fakeCurrencyFileServer.requests[1].url).to.equal('https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json?date=20030306'); @@ -305,7 +306,7 @@ describe('currency', function () { describe('when rates fail to load', () => { let bid, addBidResponse, reject; beforeEach(() => { - bid = makeBid({cpm: 100, currency: 'JPY', bidder: 'rubicoin'}); + bid = makeBid({ cpm: 100, currency: 'JPY', bidder: 'rubicoin' }); addBidResponse = sinon.spy(); reject = sinon.spy(); }) @@ -389,7 +390,7 @@ describe('currency', function () { describe('currency.addBidResponseDecorator', function () { let reject; beforeEach(() => { - reject = sinon.stub().returns({status: 'rejected'}); + reject = sinon.stub().returns({ status: 'rejected' }); }); it('should leave bid at 1 when currency support is not enabled and fromCurrency is USD', function () { @@ -457,9 +458,9 @@ describe('currency', function () { it('should reject bid when rates have not loaded when the auction times out', () => { fakeCurrencyFileServer.respondWith(JSON.stringify(getCurrencyRates())); - setConfig({'adServerCurrency': 'JPY'}); - const bid = makeBid({cpm: 1, currency: 'USD', auctionId: 'aid'}); - const noConversionBid = makeBid({cpm: 1, currency: 'JPY', auctionId: 'aid'}); + setConfig({ 'adServerCurrency': 'JPY' }); + const bid = makeBid({ cpm: 1, currency: 'USD', auctionId: 'aid' }); + const noConversionBid = makeBid({ cpm: 1, currency: 'JPY', auctionId: 'aid' }); const reject = sinon.spy(); const addBidResponse = sinon.spy(); addBidResponseHook(addBidResponse, 'au', bid, reject); @@ -557,7 +558,7 @@ describe('currency', function () { }); it('should delay auction start when auctionDelay set in module config', () => { - setConfig({auctionDelay: 2000, adServerCurrency: 'USD'}); + setConfig({ auctionDelay: 2000, adServerCurrency: 'USD' }); const reqBidsConfigObj = { auctionId: '128937' }; @@ -567,7 +568,7 @@ describe('currency', function () { }); it('should start auction when auctionDelay time passed', () => { - setConfig({auctionDelay: 2000, adServerCurrency: 'USD'}); + setConfig({ auctionDelay: 2000, adServerCurrency: 'USD' }); const reqBidsConfigObj = { auctionId: '128937' }; @@ -578,7 +579,7 @@ describe('currency', function () { }); it('should run auction if rates were fetched before auctionDelay time', () => { - setConfig({auctionDelay: 3000, adServerCurrency: 'USD'}); + setConfig({ auctionDelay: 3000, adServerCurrency: 'USD' }); const reqBidsConfigObj = { auctionId: '128937' }; diff --git a/test/spec/modules/czechAdIdSystem_spec.js b/test/spec/modules/czechAdIdSystem_spec.js index 5ce3b7fbbac..430fb1f7a79 100644 --- a/test/spec/modules/czechAdIdSystem_spec.js +++ b/test/spec/modules/czechAdIdSystem_spec.js @@ -1,7 +1,7 @@ -import {czechAdIdSubmodule, storage} from 'modules/czechAdIdSystem.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { czechAdIdSubmodule, storage } from 'modules/czechAdIdSystem.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; describe('czechAdId module', function () { let getCookieStub; @@ -21,7 +21,7 @@ describe('czechAdId module', function () { it('should return the uid when it exists in cookie', function () { getCookieStub.withArgs('czaid').returns('00000000-0000-4000-8000-000000000000'); const id = czechAdIdSubmodule.getId(); - expect(id).to.be.deep.equal({id: '00000000-0000-4000-8000-000000000000'}); + expect(id).to.be.deep.equal({ id: '00000000-0000-4000-8000-000000000000' }); }); cookieTestCasesForEmpty.forEach(testCase => it('should not return the uid when it doesnt exist in cookie', function () { @@ -35,7 +35,7 @@ describe('czechAdId module', function () { it('should return the uid when it exists in cookie', function () { getCookieStub.withArgs('czaid').returns('00000000-0000-4000-8000-000000000000'); const decoded = czechAdIdSubmodule.decode(); - expect(decoded).to.be.deep.equal({czechAdId: '00000000-0000-4000-8000-000000000000'}); + expect(decoded).to.be.deep.equal({ czechAdId: '00000000-0000-4000-8000-000000000000' }); }); }); describe('eid', () => { @@ -45,11 +45,11 @@ describe('czechAdId module', function () { it('czechAdId', () => { const id = 'some-random-id-value'; - const userId = {czechAdId: id}; + const userId = { czechAdId: id }; const [eid] = createEidsArray(userId); expect(eid).to.deep.equal({ source: 'czechadid.cz', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); }); diff --git a/test/spec/modules/dacIdSystem_spec.js b/test/spec/modules/dacIdSystem_spec.js index 0246e65a310..54a2059f3d1 100644 --- a/test/spec/modules/dacIdSystem_spec.js +++ b/test/spec/modules/dacIdSystem_spec.js @@ -82,22 +82,22 @@ describe('dacId module', function () { // valid oid, fuuid, no AoneId getCookieStub.withArgs(FUUID_COOKIE_NAME).returns(FUUID_DUMMY_VALUE); const callbackSpy = sinon.spy(); - const callback = dacIdSystemSubmodule.getId({params: {oid: configParamTestCase.params.oid[0]}}).callback; + const callback = dacIdSystemSubmodule.getId({ params: { oid: configParamTestCase.params.oid[0] } }).callback; callback(callbackSpy); const request = server.requests[0]; - request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({'uid': AONEID_DUMMY_VALUE})); - expect(callbackSpy.lastCall.lastArg).to.deep.equal({fuuid: 'dacIdTest', uid: AONEID_DUMMY_VALUE}); + request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ 'uid': AONEID_DUMMY_VALUE })); + expect(callbackSpy.lastCall.lastArg).to.deep.equal({ fuuid: 'dacIdTest', uid: AONEID_DUMMY_VALUE }); }); cookieTestCasesForEmpty.forEach(testCase => it('should return undefined when AoneId not exists & API result is empty', function () { // valid oid, fuuid, no AoneId, API result empty getCookieStub.withArgs(FUUID_COOKIE_NAME).returns(FUUID_DUMMY_VALUE); const callbackSpy = sinon.spy(); - const callback = dacIdSystemSubmodule.getId({params: {oid: configParamTestCase.params.oid[0]}}).callback; + const callback = dacIdSystemSubmodule.getId({ params: { oid: configParamTestCase.params.oid[0] } }).callback; callback(callbackSpy); const request = server.requests[0]; - request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({'uid': testCase})); - expect(callbackSpy.lastCall.lastArg).to.deep.equal({fuuid: 'dacIdTest', uid: undefined}); + request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify({ 'uid': testCase })); + expect(callbackSpy.lastCall.lastArg).to.deep.equal({ fuuid: 'dacIdTest', uid: undefined }); })); it('should return the fuuid & AoneId when they exist', function () { diff --git a/test/spec/modules/dataController_spec.js b/test/spec/modules/dataController_spec.js index 07e1c9c19f5..95beb722fa7 100644 --- a/test/spec/modules/dataController_spec.js +++ b/test/spec/modules/dataController_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {filterBidData, init} from 'modules/dataControllerModule/index.js'; -import {startAuction} from 'src/prebid.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { filterBidData, init } from 'modules/dataControllerModule/index.js'; +import { startAuction } from 'src/prebid.js'; describe('data controller', function () { let spyFn; @@ -85,7 +85,7 @@ describe('data controller', function () { afterEach(function () { config.resetConfig(); - startAuction.getHooks({hook: filterBidData}).remove(); + startAuction.getHooks({ hook: filterBidData }).remove(); }); it('filterEIDwhenSDA for All SDA ', function () { diff --git a/test/spec/modules/datablocksBidAdapter_spec.js b/test/spec/modules/datablocksBidAdapter_spec.js index 9e2b311e5c6..0ff7b89e880 100644 --- a/test/spec/modules/datablocksBidAdapter_spec.js +++ b/test/spec/modules/datablocksBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec, BotClientTests } from '../../../modules/datablocksBidAdapter.js'; import { getStorageManager } from '../../../src/storageManager.js'; -import {deepClone} from '../../../src/utils.js'; +import { deepClone } from '../../../src/utils.js'; const bid = { bidId: '2dd581a2b6281d', @@ -381,7 +381,7 @@ describe('DatablocksAdapter', function() { describe('get / store syncs', function() { it('Should return true / array', function() { - expect(spec.store_syncs([{id: 1, uid: 'test'}])).to.be.true; + expect(spec.store_syncs([{ id: 1, uid: 'test' }])).to.be.true; expect(spec.get_syncs()).to.be.a('object'); }); }) @@ -425,7 +425,7 @@ describe('DatablocksAdapter', function() { describe('getUserSyncs', function() { it('Should return array of syncs', function() { - expect(spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [res_object], {gdprApplies: true, gdpr: 1, gdpr_consent: 'consent_string'}, {})).to.be.an('array'); + expect(spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [res_object], { gdprApplies: true, gdpr: 1, gdpr_consent: 'consent_string' }, {})).to.be.an('array'); }); }); @@ -437,7 +437,7 @@ describe('DatablocksAdapter', function() { describe('onBidWon', function() { it('Should return undefined', function() { - const won_bid = {params: [{source_id: 1}], requestId: 1, adUnitCode: 'unit', auctionId: 1, size: '300x250', cpm: 10, adserverTargeting: {hb_pb: 10}, timeToRespond: 10, ttl: 10}; + const won_bid = { params: [{ source_id: 1 }], requestId: 1, adUnitCode: 'unit', auctionId: 1, size: '300x250', cpm: 10, adserverTargeting: { hb_pb: 10 }, timeToRespond: 10, ttl: 10 }; expect(spec.onBidWon(won_bid)).to.equal(undefined); }); }); diff --git a/test/spec/modules/datawrkzBidAdapter_spec.js b/test/spec/modules/datawrkzBidAdapter_spec.js index ad513c20b8b..c485889c48f 100644 --- a/test/spec/modules/datawrkzBidAdapter_spec.js +++ b/test/spec/modules/datawrkzBidAdapter_spec.js @@ -43,13 +43,13 @@ describe('datawrkzAdapterTests', function () { it('should return false when required site_id param not found', function () { const invalidBid = Object.assign({}, bid); - invalidBid.params = {'bidfloor': '1.0'} + invalidBid.params = { 'bidfloor': '1.0' } expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); it('should return false when adunit is adpod video', function () { const invalidBid = Object.assign({}, bid); - invalidBid.params = {'bidfloor': '1.0', 'site_id': SITE_ID}; + invalidBid.params = { 'bidfloor': '1.0', 'site_id': SITE_ID }; invalidBid.mediaTypes = { 'video': { 'context': 'adpod' @@ -67,12 +67,12 @@ describe('datawrkzAdapterTests', function () { 'bidderRequestId': '22edbae2733bf6', 'timeout': 3000, 'uspConsent': consentString, - 'gdprConsent': {'gdprApplies': true}, + 'gdprConsent': { 'gdprApplies': true }, }; const bannerBidRequests = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'banner': {'sizes': [[300, 250], [300, 600]]}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { 'banner': { 'sizes': [[300, 250], [300, 600]] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'sizes': [[300, 250], [300, 600]], @@ -82,8 +82,8 @@ describe('datawrkzAdapterTests', function () { }]; const bannerBidRequestsSingleArraySlotAndDeals = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{id: 'deal_1'}, {id: 'deal_2'}]}, - 'mediaTypes': {'banner': {}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{ id: 'deal_1' }, { id: 'deal_2' }] }, + 'mediaTypes': { 'banner': {} }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'sizes': [300, 250], @@ -93,15 +93,17 @@ describe('datawrkzAdapterTests', function () { }]; const nativeBidRequests = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'native': { - 'title': {'required': true, 'len': 80}, - 'image': {'required': true, 'sizes': [[300, 250]]}, - 'icon': {'required': true, 'sizes': [[50, 50]]}, - 'sponsoredBy': {'required': true}, - 'cta': {'required': true}, - 'body': {'required': true, 'len': 100} - }}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { + 'native': { + 'title': { 'required': true, 'len': 80 }, + 'image': { 'required': true, 'sizes': [[300, 250]] }, + 'icon': { 'required': true, 'sizes': [[50, 50]] }, + 'sponsoredBy': { 'required': true }, + 'cta': { 'required': true }, + 'body': { 'required': true, 'len': 100 } + } + }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -110,15 +112,17 @@ describe('datawrkzAdapterTests', function () { }]; const nativeBidRequestsSingleArraySlotAndDeals = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{id: 'deal_1'}, {id: 'deal_2'}]}, - 'mediaTypes': {'native': { - 'title': {'len': 80}, - 'image': {'sizes': [300, 250]}, - 'icon': {'sizes': [50, 50]}, - 'sponsoredBy': {}, - 'cta': {}, - 'body': {'len': 100} - }}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{ id: 'deal_1' }, { id: 'deal_2' }] }, + 'mediaTypes': { + 'native': { + 'title': { 'len': 80 }, + 'image': { 'sizes': [300, 250] }, + 'icon': { 'sizes': [50, 50] }, + 'sponsoredBy': {}, + 'cta': {}, + 'body': { 'len': 100 } + } + }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -127,8 +131,8 @@ describe('datawrkzAdapterTests', function () { }]; const instreamVideoBidRequests = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'video': {'context': 'instream', 'playerSize': [[640, 480]]}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { 'video': { 'context': 'instream', 'playerSize': [[640, 480]] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -137,8 +141,8 @@ describe('datawrkzAdapterTests', function () { }]; const instreamVideoBidRequestsSingleArraySlotAndDeals = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{id: 'deal_1'}, {id: 'deal_2'}]}, - 'mediaTypes': {'video': {'context': 'instream', 'playerSize': [640, 480]}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{ id: 'deal_1' }, { id: 'deal_2' }] }, + 'mediaTypes': { 'video': { 'context': 'instream', 'playerSize': [640, 480] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -147,8 +151,8 @@ describe('datawrkzAdapterTests', function () { }]; const outstreamVideoBidRequests = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'video': {'context': 'outstream', 'playerSize': [[640, 480]], 'mimes': ['video/mp4', 'video/x-flv']}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { 'video': { 'context': 'outstream', 'playerSize': [[640, 480]], 'mimes': ['video/mp4', 'video/x-flv'] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -157,8 +161,8 @@ describe('datawrkzAdapterTests', function () { }]; const outstreamVideoBidRequestsSingleArraySlotAndDeals = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{id: 'deal_1'}, {id: 'deal_2'}]}, - 'mediaTypes': {'video': {'context': 'outstream', 'playerSize': [640, 480], 'mimes': ['video/mp4', 'video/x-flv']}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00, 'deals': [{ id: 'deal_1' }, { id: 'deal_2' }] }, + 'mediaTypes': { 'video': { 'context': 'outstream', 'playerSize': [640, 480], 'mimes': ['video/mp4', 'video/x-flv'] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -167,7 +171,7 @@ describe('datawrkzAdapterTests', function () { }]; const bidRequestsWithNoMediaType = [{ 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -186,7 +190,7 @@ describe('datawrkzAdapterTests', function () { }); it('invalid media type in bid request', function () { - bidRequestsWithNoMediaType[0].mediaTypes = {'test': {}}; + bidRequestsWithNoMediaType[0].mediaTypes = { 'test': {} }; const requests = spec.buildRequests(bidRequestsWithNoMediaType, bidderRequest); assert.lengthOf(requests, 0); }); @@ -212,11 +216,11 @@ describe('datawrkzAdapterTests', function () { expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); expect(payload.imp).to.exist; - expect(payload).to.nested.include({'imp[0].banner.w': 300}); - expect(payload).to.nested.include({'imp[0].banner.h': 250}); - expect(payload).to.nested.include({'regs.ext.us_privacy': consentString}); - expect(payload).to.nested.include({'regs.ext.gdpr': '1'}); - expect(payload).to.nested.include({'regs.coppa': '1'}); + expect(payload).to.nested.include({ 'imp[0].banner.w': 300 }); + expect(payload).to.nested.include({ 'imp[0].banner.h': 250 }); + expect(payload).to.nested.include({ 'regs.ext.us_privacy': consentString }); + expect(payload).to.nested.include({ 'regs.ext.gdpr': '1' }); + expect(payload).to.nested.include({ 'regs.coppa': '1' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('banner'); }); @@ -227,10 +231,10 @@ describe('datawrkzAdapterTests', function () { expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); expect(payload.imp).to.exist; - expect(payload).to.nested.include({'imp[0].banner.w': 300}); - expect(payload).to.nested.include({'imp[0].banner.h': 250}); - expect(payload).to.nested.include({'imp[0].pmp.deals[0].id': 'deal_1'}); - expect(payload).to.nested.include({'imp[0].pmp.deals[1].id': 'deal_2'}); + expect(payload).to.nested.include({ 'imp[0].banner.w': 300 }); + expect(payload).to.nested.include({ 'imp[0].banner.h': 250 }); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[0].id': 'deal_1' }); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[1].id': 'deal_2' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('banner'); }); @@ -243,9 +247,9 @@ describe('datawrkzAdapterTests', function () { expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); expect(payload.imp[0].native.request).to.exist; - expect(payload).to.nested.include({'regs.ext.us_privacy': consentString}); - expect(payload).to.nested.include({'regs.ext.gdpr': '1'}); - expect(payload).to.nested.include({'regs.coppa': '1'}); + expect(payload).to.nested.include({ 'regs.ext.us_privacy': consentString }); + expect(payload).to.nested.include({ 'regs.ext.gdpr': '1' }); + expect(payload).to.nested.include({ 'regs.coppa': '1' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('native'); }); @@ -257,8 +261,8 @@ describe('datawrkzAdapterTests', function () { expect(requests[0].url).to.equal(FINAL_URL); expect(payload.imp).to.exist; expect(payload.imp[0].native.request).to.exist; - expect(payload).to.nested.include({'imp[0].pmp.deals[0].id': 'deal_1'}); - expect(payload).to.nested.include({'imp[0].pmp.deals[1].id': 'deal_2'}); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[0].id': 'deal_1' }); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[1].id': 'deal_2' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('native'); }); @@ -270,9 +274,9 @@ describe('datawrkzAdapterTests', function () { const payload = JSON.parse(requests[0].data); expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); - expect(payload).to.nested.include({'regs.ext.us_privacy': consentString}); - expect(payload).to.nested.include({'regs.ext.gdpr': '1'}); - expect(payload).to.nested.include({'regs.coppa': '1'}); + expect(payload).to.nested.include({ 'regs.ext.us_privacy': consentString }); + expect(payload).to.nested.include({ 'regs.ext.gdpr': '1' }); + expect(payload).to.nested.include({ 'regs.coppa': '1' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('video'); }); @@ -293,11 +297,11 @@ describe('datawrkzAdapterTests', function () { const payload = JSON.parse(requests[0].data); expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); - expect(payload).to.nested.include({'imp[0].video.w': 640}); - expect(payload).to.nested.include({'imp[0].video.h': 480}); - expect(payload).to.nested.include({'regs.ext.us_privacy': consentString}); - expect(payload).to.nested.include({'regs.ext.gdpr': '1'}); - expect(payload).to.nested.include({'regs.coppa': '1'}); + expect(payload).to.nested.include({ 'imp[0].video.w': 640 }); + expect(payload).to.nested.include({ 'imp[0].video.h': 480 }); + expect(payload).to.nested.include({ 'regs.ext.us_privacy': consentString }); + expect(payload).to.nested.include({ 'regs.ext.gdpr': '1' }); + expect(payload).to.nested.include({ 'regs.coppa': '1' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('video'); }); @@ -307,10 +311,10 @@ describe('datawrkzAdapterTests', function () { const payload = JSON.parse(requests[0].data); expect(requests[0].method).to.equal('POST'); expect(requests[0].url).to.equal(FINAL_URL); - expect(payload).to.nested.include({'imp[0].video.w': 640}); - expect(payload).to.nested.include({'imp[0].video.h': 480}); - expect(payload).to.nested.include({'imp[0].pmp.deals[0].id': 'deal_1'}); - expect(payload).to.nested.include({'imp[0].pmp.deals[1].id': 'deal_2'}); + expect(payload).to.nested.include({ 'imp[0].video.w': 640 }); + expect(payload).to.nested.include({ 'imp[0].video.h': 480 }); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[0].id': 'deal_1' }); + expect(payload).to.nested.include({ 'imp[0].pmp.deals[1].id': 'deal_2' }); expect(requests[0].bidRequest).to.exist; expect(requests[0].bidRequest.requestedMediaType).to.equal('video'); }); @@ -319,8 +323,8 @@ describe('datawrkzAdapterTests', function () { describe('interpretResponse', function () { const bidRequest = { 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'banner': {'sizes': [[300, 250], [300, 600]]}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { 'banner': { 'sizes': [[300, 250], [300, 600]] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'sizes': [[300, 250], [300, 600]], @@ -331,15 +335,17 @@ describe('datawrkzAdapterTests', function () { }; const nativeBidRequest = { 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'native': { - 'title': {'required': true, 'len': 80}, - 'image': {'required': true, 'sizes': [300, 250]}, - 'icon': {'required': true, 'sizes': [50, 50]}, - 'sponsoredBy': {'required': true}, - 'cta': {'required': true}, - 'body': {'required': true} - }}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { + 'native': { + 'title': { 'required': true, 'len': 80 }, + 'image': { 'required': true, 'sizes': [300, 250] }, + 'icon': { 'required': true, 'sizes': [50, 50] }, + 'sponsoredBy': { 'required': true }, + 'cta': { 'required': true }, + 'body': { 'required': true } + } + }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -347,18 +353,18 @@ describe('datawrkzAdapterTests', function () { 'auctionId': 'auctionId', 'requestedMediaType': 'native', 'assets': [ - {'id': 1, 'required': 1, 'title': {'len': 80}}, - {'id': 2, 'required': 1, 'img': {'type': 3, 'w': 300, 'h': 250}}, - {'id': 3, 'required': 1, 'img': {'type': 1, 'w': 50, 'h': 50}}, - {'id': 4, 'required': 1, 'data': {'type': 1}}, - {'id': 5, 'required': 1, 'data': {'type': 12}}, - {'id': 6, 'required': 1, 'data': {'type': 2, 'len': 100}} + { 'id': 1, 'required': 1, 'title': { 'len': 80 } }, + { 'id': 2, 'required': 1, 'img': { 'type': 3, 'w': 300, 'h': 250 } }, + { 'id': 3, 'required': 1, 'img': { 'type': 1, 'w': 50, 'h': 50 } }, + { 'id': 4, 'required': 1, 'data': { 'type': 1 } }, + { 'id': 5, 'required': 1, 'data': { 'type': 12 } }, + { 'id': 6, 'required': 1, 'data': { 'type': 2, 'len': 100 } } ] }; const instreamVideoBidRequest = { 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, 'bidfloor': 1.00}, - 'mediaTypes': {'video': {'context': 'instream', 'playerSize': [640, 480]}}, + 'params': { 'site_id': SITE_ID, 'bidfloor': 1.00 }, + 'mediaTypes': { 'video': { 'context': 'instream', 'playerSize': [640, 480] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -368,12 +374,14 @@ describe('datawrkzAdapterTests', function () { }; const outstreamVideoBidRequest = { 'bidder': BIDDER_CODE, - 'params': {'site_id': SITE_ID, + 'params': { + 'site_id': SITE_ID, 'bidfloor': 1.00, 'outstreamType': 'slider_top_left', 'outstreamConfig': - {'ad_unit_audio': 1, 'show_player_close_button_after': 5, 'hide_player_control': 0}}, - 'mediaTypes': {'video': {'context': 'outstream', 'playerSize': [640, 480]}}, + { 'ad_unit_audio': 1, 'show_player_close_button_after': 5, 'hide_player_control': 0 } + }, + 'mediaTypes': { 'video': { 'context': 'outstream', 'playerSize': [640, 480] } }, 'adUnitCode': 'adUnitCode', 'transactionId': 'transactionId', 'bidId': 'bidId', @@ -394,37 +402,37 @@ describe('datawrkzAdapterTests', function () { }); it('check if id missing in response', function () { - const serverResponse = {'body': {'seatbid': [{}]}, 'headers': {}}; + const serverResponse = { 'body': { 'seatbid': [{}] }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.deep.equal([]); }); it('check if seatbid present in response', function () { - const serverResponse = {'body': {'id': 'id'}, 'headers': {}}; + const serverResponse = { 'body': { 'id': 'id' }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.deep.equal([]); }); it('check empty array response seatbid', function () { - const serverResponse = {'body': {'id': 'id', 'seatbid': []}, 'headers': {}}; + const serverResponse = { 'body': { 'id': 'id', 'seatbid': [] }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.deep.equal([]); }); it('check bid present in seatbid', function () { - const serverResponse = {'body': {'id': 'id', 'seatbid': [{}]}, 'headers': {}}; + const serverResponse = { 'body': { 'id': 'id', 'seatbid': [{}] }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.have.lengthOf(0); }); it('check empty array bid in seatbid', function () { - const serverResponse = {'body': {'id': 'id', 'seatbid': [{'bid': []}]}, 'headers': {}}; + const serverResponse = { 'body': { 'id': 'id', 'seatbid': [{ 'bid': [] }] }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.have.lengthOf(0); }); it('banner response missing bid price', function () { - const serverResponse = {'body': {'id': 'id', 'seatbid': [{'bid': [{'id': 1}]}]}, 'headers': {}}; + const serverResponse = { 'body': { 'id': 'id', 'seatbid': [{ 'bid': [{ 'id': 1 }] }] }, 'headers': {} }; const result = spec.interpretResponse(serverResponse, request); expect(result).to.have.lengthOf(1); expect(result[0].requestId).to.equal('bidId'); diff --git a/test/spec/modules/debugging_mod_spec.js b/test/spec/modules/debugging_mod_spec.js index 4989eb7c2e3..39737272bed 100644 --- a/test/spec/modules/debugging_mod_spec.js +++ b/test/spec/modules/debugging_mod_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {makebidInterceptor} from '../../../modules/debugging/bidInterceptor.js'; +import { expect } from 'chai'; +import { makebidInterceptor } from '../../../modules/debugging/bidInterceptor.js'; import { makeBidderBidInterceptor, disableDebugging, @@ -7,9 +7,9 @@ import { sessionLoader, } from '../../../modules/debugging/debugging.js'; import '../../../modules/debugging/index.js'; -import {makePbsInterceptor} from '../../../modules/debugging/pbsInterceptor.js'; -import {config} from '../../../src/config.js'; -import {hook} from '../../../src/hook.js'; +import { makePbsInterceptor } from '../../../modules/debugging/pbsInterceptor.js'; +import { config } from '../../../src/config.js'; +import { hook } from '../../../src/hook.js'; import { addBidderRequestsBound, addBidderRequestsHook, @@ -17,18 +17,18 @@ import { addBidResponseHook, } from '../../../modules/debugging/legacy.js'; import * as utils from '../../../src/utils.js'; -import {addBidderRequests, addBidResponse} from '../../../src/auction.js'; -import {prefixLog} from '../../../src/utils.js'; -import {createBid} from '../../../src/bidfactory.js'; -import {VIDEO, BANNER, NATIVE} from '../../../src/mediaTypes.js'; -import {Renderer} from '../../../src/Renderer.js'; +import { addBidderRequests, addBidResponse } from '../../../src/auction.js'; +import { prefixLog } from '../../../src/utils.js'; +import { createBid } from '../../../src/bidfactory.js'; +import { VIDEO, BANNER, NATIVE } from '../../../src/mediaTypes.js'; +import { Renderer } from '../../../src/Renderer.js'; describe('bid interceptor', () => { let interceptor, mockSetTimeout; beforeEach(() => { mockSetTimeout = sinon.stub().callsFake((fn) => fn()); - const BidInterceptor = makebidInterceptor({utils, VIDEO, BANNER, NATIVE, Renderer}) - interceptor = new BidInterceptor({setTimeout: mockSetTimeout, logger: prefixLog('TEST')}); + const BidInterceptor = makebidInterceptor({ utils, VIDEO, BANNER, NATIVE, Renderer }) + interceptor = new BidInterceptor({ setTimeout: mockSetTimeout, logger: prefixLog('TEST') }); }); function setRules(...rules) { @@ -48,8 +48,8 @@ describe('bid interceptor', () => { set: new Set(), }).forEach(([test, arg]) => { it(`should filter out ${test}`, () => { - const valid = [{key1: 'value'}, {key2: 'value'}]; - const ser = interceptor.serializeConfig([...valid, {outer: {inner: arg}}]); + const valid = [{ key1: 'value' }, { key2: 'value' }]; + const ser = interceptor.serializeConfig([...valid, { outer: { inner: arg } }]); expect(ser).to.eql(valid); }); }); @@ -57,33 +57,33 @@ describe('bid interceptor', () => { describe('match()', () => { Object.entries({ - value: {key: 'value'}, - regex: {key: /^value$/}, + value: { key: 'value' }, + regex: { key: /^value$/ }, 'function': (o) => o.key === 'value' }).forEach(([test, matcher]) => { describe(`by ${test}`, () => { it('should work on matching top-level properties', () => { - setRules({when: matcher}); - const rule = interceptor.match({key: 'value'}); + setRules({ when: matcher }); + const rule = interceptor.match({ key: 'value' }); expect(rule).to.not.eql(null); }); it('should work on matching nested properties', () => { - setRules({when: {outer: {inner: matcher}}}); - const rule = interceptor.match({outer: {inner: {key: 'value'}}}); + setRules({ when: { outer: { inner: matcher } } }); + const rule = interceptor.match({ outer: { inner: { key: 'value' } } }); expect(rule).to.not.eql(null); }); it('should not work on non-matching inputs', () => { - setRules({when: matcher}); - expect(interceptor.match({key: 'different-value'})).to.not.be.ok; - expect(interceptor.match({differentKey: 'value'})).to.not.be.ok; + setRules({ when: matcher }); + expect(interceptor.match({ key: 'different-value' })).to.not.be.ok; + expect(interceptor.match({ differentKey: 'value' })).to.not.be.ok; }); }); }); it('should respect rule order', () => { - setRules({when: {key: 'value'}}, {when: {}}, {when: {}}); + setRules({ when: { key: 'value' } }, { when: {} }, { when: {} }); const rule = interceptor.match({}); expect(rule.no).to.equal(2); }); @@ -91,11 +91,11 @@ describe('bid interceptor', () => { it('should pass extra arguments to property function matchers', () => { const matchDef = { key: sinon.stub(), - outer: {inner: {key: sinon.stub()}} + outer: { inner: { key: sinon.stub() } } }; const extraArgs = [{}, {}]; - setRules({when: matchDef}); - interceptor.match({key: {}, outer: {inner: {key: {}}}}, ...extraArgs); + setRules({ when: matchDef }); + interceptor.match({ key: {}, outer: { inner: { key: {} } } }, ...extraArgs); [matchDef.key, matchDef.outer.inner.key].forEach((fn) => { expect(fn.calledOnceWith(sinon.match.any, ...extraArgs.map(sinon.match.same))).to.be.true; }); @@ -103,7 +103,7 @@ describe('bid interceptor', () => { it('should pass extra arguments to single-function matcher', () => { const matchDef = sinon.stub(); - setRules({when: matchDef}); + setRules({ when: matchDef }); const args = [{}, {}, {}]; interceptor.match(...args); expect(matchDef.calledOnceWith(...args.map(sinon.match.same))).to.be.true; @@ -111,8 +111,8 @@ describe('bid interceptor', () => { }); describe('rule', () => { - function matchingRule({replace, options, paapi}) { - setRules({when: {}, then: replace, options: options, paapi}); + function matchingRule({ replace, options, paapi }) { + setRules({ when: {}, then: replace, options: options, paapi }); return interceptor.match({}); } @@ -127,27 +127,27 @@ describe('bid interceptor', () => { }); Object.entries({ - value: {key: 'value'}, - 'function': () => ({key: 'value'}) + value: { key: 'value' }, + 'function': () => ({ key: 'value' }) }).forEach(([test, replDef]) => { describe(`by ${test}`, () => { it('should merge top-level properties with replace definition', () => { - const result = matchingRule({replace: replDef}).replace({}); + const result = matchingRule({ replace: replDef }).replace({}); expect(result).to.include.keys(REQUIRED_KEYS); expect(result.key).to.equal('value'); }); it('should merge nested properties with replace definition', () => { - const result = matchingRule({replace: {outer: {inner: replDef}}}).replace({}); + const result = matchingRule({ replace: { outer: { inner: replDef } } }).replace({}); expect(result).to.include.keys(REQUIRED_KEYS); - expect(result.outer.inner).to.eql({key: 'value'}); + expect(result.outer.inner).to.eql({ key: 'value' }); }); it('should respect array vs object definitions', () => { - const result = matchingRule({replace: {item: [replDef]}}).replace({}); + const result = matchingRule({ replace: { item: [replDef] } }).replace({}); expect(result.item).to.be.an('array'); expect(result.item.length).to.equal(1); - expect(result.item[0]).to.eql({key: 'value'}); + expect(result.item[0]).to.eql({ key: 'value' }); }); }); }); @@ -155,17 +155,17 @@ describe('bid interceptor', () => { it('should pass extra arguments to single function replacer', () => { const replDef = sinon.stub(); const args = [{}, {}, {}]; - matchingRule({replace: replDef}).replace(...args); + matchingRule({ replace: replDef }).replace(...args); expect(replDef.calledOnceWith(...args.map(sinon.match.same))).to.be.true; }); it('should pass extra arguments to function property replacers', () => { const replDef = { key: sinon.stub(), - outer: {inner: {key: sinon.stub()}} + outer: { inner: { key: sinon.stub() } } }; const args = [{}, {}, {}]; - matchingRule({replace: replDef}).replace(...args); + matchingRule({ replace: replDef }).replace(...args); [replDef.key, replDef.outer.inner.key].forEach((repl) => { expect(repl.calledOnceWith(...args.map(sinon.match.same))).to.be.true; }); @@ -175,17 +175,17 @@ describe('bid interceptor', () => { describe('paapi', () => { it('should accept literals', () => { const mockConfig = [ - {config: {paapi: 1}}, - {config: {paapi: 2}} + { config: { paapi: 1 } }, + { config: { paapi: 2 } } ] - const paapi = matchingRule({paapi: mockConfig}).paapi({}); + const paapi = matchingRule({ paapi: mockConfig }).paapi({}); expect(paapi).to.eql(mockConfig); }); it('should accept a function and pass extra args to it', () => { const paapiDef = sinon.stub(); const args = [{}, {}, {}]; - matchingRule({paapi: paapiDef}).paapi(...args); + matchingRule({ paapi: paapiDef }).paapi(...args); expect(paapiDef.calledOnceWith(...args.map(sinon.match.same))).to.be.true; }); @@ -195,19 +195,19 @@ describe('bid interceptor', () => { }).forEach(([t, makeConfigs]) => { describe(`when paapi is defined as a ${t}`, () => { it('should wrap top-level configs in "config"', () => { - const cfg = {decisionLogicURL: 'example'}; - expect(matchingRule({paapi: makeConfigs(cfg)}).paapi({})).to.eql([{ + const cfg = { decisionLogicURL: 'example' }; + expect(matchingRule({ paapi: makeConfigs(cfg) }).paapi({})).to.eql([{ config: cfg }]) }); Object.entries({ - 'config': {config: 1}, - 'igb': {igb: 1}, - 'config and igb': {config: 1, igb: 2} + 'config': { config: 1 }, + 'igb': { igb: 1 }, + 'config and igb': { config: 1, igb: 2 } }).forEach(([t, cfg]) => { it(`should not wrap configs that define top-level ${t}`, () => { - expect(matchingRule({paapi: makeConfigs(cfg)}).paapi({})).to.eql([cfg]); + expect(matchingRule({ paapi: makeConfigs(cfg) }).paapi({})).to.eql([cfg]); }) }) }) @@ -216,15 +216,15 @@ describe('bid interceptor', () => { describe('.options', () => { it('should include default rule options', () => { - const optDef = {someOption: 'value'}; - const ruleOptions = matchingRule({options: optDef}).options; + const optDef = { someOption: 'value' }; + const ruleOptions = matchingRule({ options: optDef }).options; expect(ruleOptions).to.include(optDef); expect(ruleOptions).to.include(interceptor.DEFAULT_RULE_OPTIONS); }); it('should override defaults', () => { - const optDef = {delay: 123}; - const ruleOptions = matchingRule({options: optDef}).options; + const optDef = { delay: 123 }; + const ruleOptions = matchingRule({ options: optDef }).options; expect(ruleOptions).to.eql(optDef); }); }); @@ -234,8 +234,8 @@ describe('bid interceptor', () => { let done, addBid, addPaapiConfig; function intercept(args = {}) { - const bidRequest = {bids: args.bids || []}; - return interceptor.intercept(Object.assign({bidRequest, done, addBid, addPaapiConfig}, args)); + const bidRequest = { bids: args.bids || [] }; + return interceptor.intercept(Object.assign({ bidRequest, done, addBid, addPaapiConfig }, args)); } beforeEach(() => { @@ -248,7 +248,7 @@ describe('bid interceptor', () => { it('should return untouched bids and bidRequest', () => { const bids = [{}, {}]; const bidRequest = {}; - const result = intercept({bids, bidRequest}); + const result = intercept({ bids, bidRequest }); expect(result.bids).to.equal(bids); expect(result.bidRequest).to.equal(bidRequest); }); @@ -271,34 +271,34 @@ describe('bid interceptor', () => { const DELAY_2 = 321; const REQUEST = { bids: [ - {id: 1, match: false}, - {id: 2, match: 1}, - {id: 3, match: 2} + { id: 1, match: false }, + { id: 2, match: 1 }, + { id: 3, match: 2 } ] }; beforeEach(() => { match1 = sinon.stub().callsFake((bid) => bid.match === 1); match2 = sinon.stub().callsFake((bid) => bid.match === 2); - repl1 = sinon.stub().returns({replace: 1}); - repl2 = sinon.stub().returns({replace: 2}); + repl1 = sinon.stub().returns({ replace: 1 }); + repl2 = sinon.stub().returns({ replace: 2 }); setRules( - {when: match1, then: repl1, options: {delay: DELAY_1}}, - {when: match2, then: repl2, options: {delay: DELAY_2}}, + { when: match1, then: repl1, options: { delay: DELAY_1 } }, + { when: match2, then: repl2, options: { delay: DELAY_2 } }, ); }); it('should return only non-matching bids', () => { - const {bids, bidRequest} = intercept({bidRequest: REQUEST}); + const { bids, bidRequest } = intercept({ bidRequest: REQUEST }); expect(bids).to.eql([REQUEST.bids[0]]); expect(bidRequest.bids).to.eql([REQUEST.bids[0]]); }); it('should call addBid for each matching bid', () => { - intercept({bidRequest: REQUEST}); + intercept({ bidRequest: REQUEST }); expect(addBid.callCount).to.equal(2); - expect(addBid.calledWith(sinon.match({replace: 1, isDebug: true}), REQUEST.bids[1])).to.be.true; - expect(addBid.calledWith(sinon.match({replace: 2, isDebug: true}), REQUEST.bids[2])).to.be.true; + expect(addBid.calledWith(sinon.match({ replace: 1, isDebug: true }), REQUEST.bids[1])).to.be.true; + expect(addBid.calledWith(sinon.match({ replace: 2, isDebug: true }), REQUEST.bids[2])).to.be.true; [DELAY_1, DELAY_2].forEach((delay) => { expect(mockSetTimeout.calledWith(sinon.match.any, delay)).to.be.true; }); @@ -306,34 +306,34 @@ describe('bid interceptor', () => { it('should call addPaapiConfigs when provided', () => { const mockPaapiConfigs = [ - {config: {paapi: 1}}, - {config: {paapi: 2}} + { config: { paapi: 1 } }, + { config: { paapi: 2 } } ] setRules({ - when: {id: 2}, + when: { id: 2 }, paapi: mockPaapiConfigs, }); - intercept({bidRequest: REQUEST}); + intercept({ bidRequest: REQUEST }); expect(addPaapiConfig.callCount).to.eql(2); mockPaapiConfigs.forEach(cfg => sinon.assert.calledWith(addPaapiConfig, cfg)) }) it('should not call onBid when then is null', () => { setRules({ - when: {id: 2}, + when: { id: 2 }, then: null }); - intercept({bidRequest: REQUEST}); + intercept({ bidRequest: REQUEST }); sinon.assert.notCalled(addBid); }) it('should call done()', () => { - intercept({bidRequest: REQUEST}); + intercept({ bidRequest: REQUEST }); expect(done.calledOnce).to.be.true; }); it('should pass bid and bidRequest to match and replace functions', () => { - intercept({bidRequest: REQUEST}); + intercept({ bidRequest: REQUEST }); Object.entries({ 1: [match1, repl1], 2: [match2, repl2] @@ -351,7 +351,7 @@ describe('Debugging config', () => { it('should behave gracefully when sessionStorage throws', () => { const logError = sinon.stub(); const getStorage = () => { throw new Error() }; - getConfig({enabled: false}, {getStorage, logger: {logError}, hook, utils}); + getConfig({ enabled: false }, { getStorage, logger: { logError }, hook, utils }); expect(logError.called).to.be.true; }); }); @@ -359,12 +359,12 @@ describe('Debugging config', () => { describe('bidderBidInterceptor', () => { let next, interceptBids, onCompletion, interceptResult, done, addBid, wrapCallback, addPaapiConfig, wrapped, bidderBidInterceptor; - function interceptorArgs({spec = {}, bids = [], bidRequest = {}, ajax = {}, cbs = {}} = {}) { - return [next, interceptBids, spec, bids, bidRequest, ajax, wrapCallback, Object.assign({onCompletion}, cbs)]; + function interceptorArgs({ spec = {}, bids = [], bidRequest = {}, ajax = {}, cbs = {} } = {}) { + return [next, interceptBids, spec, bids, bidRequest, ajax, wrapCallback, Object.assign({ onCompletion }, cbs)]; } beforeEach(() => { - bidderBidInterceptor = makeBidderBidInterceptor({utils}); + bidderBidInterceptor = makeBidderBidInterceptor({ utils }); next = sinon.spy(); wrapped = false; wrapCallback = sinon.stub().callsFake(cb => { @@ -385,14 +385,14 @@ describe('bidderBidInterceptor', () => { return interceptResult; }); onCompletion = sinon.spy(); - interceptResult = {bids: [], bidRequest: {}}; + interceptResult = { bids: [], bidRequest: {} }; }); it('should pass to interceptBid an addBid that triggers onBid', () => { const onBid = sinon.stub().callsFake(() => { expect(wrapped).to.be.true; }); - bidderBidInterceptor(...interceptorArgs({cbs: {onBid}})); + bidderBidInterceptor(...interceptorArgs({ cbs: { onBid } })); const bid = { bidder: 'bidder' }; @@ -404,9 +404,9 @@ describe('bidderBidInterceptor', () => { const onPaapi = sinon.stub().callsFake(() => { expect(wrapped).to.be.true; }); - bidderBidInterceptor(...interceptorArgs({cbs: {onPaapi}})); - addPaapiConfig({paapi: 'config'}, {bidId: 'bidId'}); - sinon.assert.calledWith(onPaapi, {paapi: 'config', bidId: 'bidId'}) + bidderBidInterceptor(...interceptorArgs({ cbs: { onPaapi } })); + addPaapiConfig({ paapi: 'config' }, { bidId: 'bidId' }); + sinon.assert.calledWith(onPaapi, { paapi: 'config', bidId: 'bidId' }) }) describe('with no remaining bids', () => { @@ -419,7 +419,7 @@ describe('bidderBidInterceptor', () => { it('should call onResponse', () => { const onResponse = sinon.stub(); - bidderBidInterceptor(...interceptorArgs({cbs: {onResponse}})); + bidderBidInterceptor(...interceptorArgs({ cbs: { onResponse } })); sinon.assert.called(onResponse); }) @@ -430,9 +430,9 @@ describe('bidderBidInterceptor', () => { }); describe('with remaining bids', () => { - const REMAINING_BIDS = [{id: 1}, {id: 2}]; + const REMAINING_BIDS = [{ id: 1 }, { id: 2 }]; beforeEach(() => { - interceptResult = {bids: REMAINING_BIDS, bidRequest: {bids: REMAINING_BIDS}}; + interceptResult = { bids: REMAINING_BIDS, bidRequest: { bids: REMAINING_BIDS } }; }); it('should call next', () => { @@ -441,7 +441,7 @@ describe('bidderBidInterceptor', () => { onRequest: {}, onBid: {} }; - const args = interceptorArgs({cbs: callbacks}); + const args = interceptorArgs({ cbs: callbacks }); const expectedNextArgs = [ args[2], interceptResult.bids, @@ -469,7 +469,7 @@ describe('bidderBidInterceptor', () => { }); describe('pbsBidInterceptor', () => { - const EMPTY_INT_RES = {bids: [], bidRequest: {bids: []}}; + const EMPTY_INT_RES = { bids: [], bidRequest: { bids: [] } }; let next, interceptBids, s2sBidRequest, bidRequests, ajax, onResponse, onError, onBid, interceptResults, addBids, dones, reqIdx; @@ -487,22 +487,22 @@ describe('pbsBidInterceptor', () => { return interceptResults[reqIdx++]; }); s2sBidRequest = {}; - bidRequests = [{bids: []}, {bids: []}]; + bidRequests = [{ bids: [] }, { bids: [] }]; interceptResults = [EMPTY_INT_RES, EMPTY_INT_RES]; }); - const pbsBidInterceptor = makePbsInterceptor({createBid, utils}); + const pbsBidInterceptor = makePbsInterceptor({ createBid, utils }); function callInterceptor() { - return pbsBidInterceptor(next, interceptBids, s2sBidRequest, bidRequests, ajax, {onResponse, onError, onBid}); + return pbsBidInterceptor(next, interceptBids, s2sBidRequest, bidRequests, ajax, { onResponse, onError, onBid }); } it('passes addBids that trigger onBid', () => { callInterceptor(); bidRequests.forEach((_, i) => { - const bid = {adUnitCode: i, prop: i}; - const bidRequest = {req: i}; + const bid = { adUnitCode: i, prop: i }; + const bidRequest = { req: i }; addBids[i](bid, bidRequest); - expect(onBid.calledWith({adUnit: i, bid: sinon.match(bid)})); + expect(onBid.calledWith({ adUnit: i, bid: sinon.match(bid) })); }); }); @@ -527,21 +527,21 @@ describe('pbsBidInterceptor', () => { let matchingBids; beforeEach(() => { matchingBids = [ - [{bidId: 1, matching: true}, {bidId: 2, matching: true}], + [{ bidId: 1, matching: true }, { bidId: 2, matching: true }], [], - [{bidId: 3, matching: true}] + [{ bidId: 3, matching: true }] ]; - interceptResults = matchingBids.map((bids) => ({bids, bidRequest: {bids}})); + interceptResults = matchingBids.map((bids) => ({ bids, bidRequest: { bids } })); s2sBidRequest = { ad_units: [ - {bids: [{bid_id: 1, matching: true}, {bid_id: 3, matching: true}, {bid_id: 100}, {bid_id: 101}]}, - {bids: [{bid_id: 2, matching: true}, {bid_id: 110}, {bid_id: 111}]}, - {bids: [{bid_id: 120}]} + { bids: [{ bid_id: 1, matching: true }, { bid_id: 3, matching: true }, { bid_id: 100 }, { bid_id: 101 }] }, + { bids: [{ bid_id: 2, matching: true }, { bid_id: 110 }, { bid_id: 111 }] }, + { bids: [{ bid_id: 120 }] } ] }; bidRequests = matchingBids.map((mBids, i) => [ - {bidId: 100 + (i * 10)}, - {bidId: 101 + (i * 10)}, + { bidId: 100 + (i * 10) }, + { bidId: 101 + (i * 10) }, ...mBids ]); }); @@ -571,7 +571,7 @@ describe('pbsBidInterceptor', () => { const passedBidReqs = next.args[0][1]; interceptResults .filter((r) => r.bids.length > 0) - .forEach(({bidRequest}, i) => { + .forEach(({ bidRequest }, i) => { expect(passedBidReqs[i]).to.equal(bidRequest); }); }); @@ -612,20 +612,20 @@ describe('bid overrides', function () { }); afterEach(function () { - disableDebugging({hook, logger}); + disableDebugging({ hook, logger }); }); it('should happen when enabled with setConfig', function () { getConfig({ enabled: true - }, {config, hook, logger, utils}); + }, { config, hook, logger, utils }); expect(addBidResponse.getHooks().some(hook => hook.hook === addBidResponseBound)).to.equal(true); expect(addBidderRequests.getHooks().some(hook => hook.hook === addBidderRequestsBound)).to.equal(true); }); it('should happen when configuration found in sessionStorage', function () { sessionLoader({ - storage: {getItem: () => ('{"enabled": true}')}, + storage: { getItem: () => ('{"enabled": true}') }, config, hook, logger @@ -677,7 +677,7 @@ describe('bid overrides', function () { const next = (adUnitCode, bid) => { bids.push(bid); }; - addBidResponseHook.bind({overrides, logger})(next, bid.adUnitCode, bid); + addBidResponseHook.bind({ overrides, logger })(next, bid.adUnitCode, bid); }); } @@ -786,7 +786,7 @@ describe('bid overrides', function () { const next = (b) => { bidderRequests = b; }; - addBidderRequestsHook.bind({overrides, logger})(next, mockBidRequests); + addBidderRequestsHook.bind({ overrides, logger })(next, mockBidRequests); } it('should allow us to exclude bidders', function () { diff --git a/test/spec/modules/deepintentBidAdapter_spec.js b/test/spec/modules/deepintentBidAdapter_spec.js index ead1c8ecc7d..b14faa92b56 100644 --- a/test/spec/modules/deepintentBidAdapter_spec.js +++ b/test/spec/modules/deepintentBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/deepintentBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/deepintentBidAdapter.js'; import * as utils from '../../../src/utils.js'; describe('Deepintent adapter', function () { @@ -376,7 +376,7 @@ describe('Deepintent adapter', function () { }); describe('GPP and coppa', function() { it('Request params check with GPP Consent', function () { - const bidderReq = {gppConsent: {gppString: 'gpp-string-test', applicableSections: [5]}}; + const bidderReq = { gppConsent: { gppString: 'gpp-string-test', applicableSections: [5] } }; const bRequest = spec.buildRequests(request, bidderReq); const data = JSON.parse(bRequest.data); expect(data.regs.gpp).to.equal('gpp-string-test'); @@ -397,7 +397,7 @@ describe('Deepintent adapter', function () { expect(data.regs.gpp_sid[0]).to.equal(5); }); it('should include coppa flag in bid request if coppa is set to true', () => { - const bidderReq = {ortb2: {regs: {coppa: 1}}}; + const bidderReq = { ortb2: { regs: { coppa: 1 } } }; const bRequest = spec.buildRequests(request, bidderReq); const data = JSON.parse(bRequest.data); expect(data.regs.coppa).to.equal(1); diff --git a/test/spec/modules/deepintentDpesIdsystem_spec.js b/test/spec/modules/deepintentDpesIdsystem_spec.js index 8f8c100afc8..63a9710e4e0 100644 --- a/test/spec/modules/deepintentDpesIdsystem_spec.js +++ b/test/spec/modules/deepintentDpesIdsystem_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; import { deepintentDpesSubmodule } from 'modules/deepintentDpesIdSystem.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; -const DI_COOKIE_OBJECT = {id: '2cf40748c4f7f60d343336e08f80dc99'}; +const DI_COOKIE_OBJECT = { id: '2cf40748c4f7f60d343336e08f80dc99' }; const DI_UPDATED_STORAGE = '2cf40748c4f7f60d343336e08f80dc99'; const cookieConfig = { @@ -44,11 +44,11 @@ describe('Deepintent DPES System', () => { describe('Deepintent Dpes System : test "decode" method', () => { it('Get the correct decoded value for dpes id, if an object is set return object', () => { - expect(deepintentDpesSubmodule.decode(DI_COOKIE_OBJECT, cookieConfig)).to.deep.equal({'deepintentId': DI_COOKIE_OBJECT}); + expect(deepintentDpesSubmodule.decode(DI_COOKIE_OBJECT, cookieConfig)).to.deep.equal({ 'deepintentId': DI_COOKIE_OBJECT }); }); it('Get the correct decoded value for dpes id, if a string is set return string', () => { - expect(deepintentDpesSubmodule.decode(DI_UPDATED_STORAGE, {})).to.deep.equal({'deepintentId': DI_UPDATED_STORAGE}); + expect(deepintentDpesSubmodule.decode(DI_UPDATED_STORAGE, {})).to.deep.equal({ 'deepintentId': DI_UPDATED_STORAGE }); }); }); @@ -73,7 +73,7 @@ describe('Deepintent DPES System', () => { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'deepintent.com', - uids: [{id: 'some-random-id-value', atype: 3}] + uids: [{ id: 'some-random-id-value', atype: 3 }] }); }); }) diff --git a/test/spec/modules/deltaprojectsBidAdapter_spec.js b/test/spec/modules/deltaprojectsBidAdapter_spec.js index 30f709f0a06..6cea023b81b 100644 --- a/test/spec/modules/deltaprojectsBidAdapter_spec.js +++ b/test/spec/modules/deltaprojectsBidAdapter_spec.js @@ -57,7 +57,7 @@ describe('deltaprojectsBidAdapter', function() { auctionId: '1d1a030790a475', } const bidRequests = [BIDREQ]; - const bannerRequest = spec.buildRequests(bidRequests, {refererInfo: { page: BID_REQ_REFER, domain: BID_REQ_DOMAIN }})[0]; + const bannerRequest = spec.buildRequests(bidRequests, { refererInfo: { page: BID_REQ_REFER, domain: BID_REQ_DOMAIN } })[0]; const bannerRequestBody = bannerRequest.data; it('send bid request with test tag if it is set in the param', function () { @@ -143,12 +143,12 @@ describe('deltaprojectsBidAdapter', function() { it('should handle gdpr applies being undefined', function() { const gdprRequestBody = getGdprRequestBody(undefined, consentString); - expect(gdprRequestBody.regs).to.deep.equal({ext: {}}); + expect(gdprRequestBody.regs).to.deep.equal({ ext: {} }); expect(gdprRequestBody.user.ext.consent).to.equal(consentString); }) it('should handle gdpr consent being undefined', function() { - const gdprRequest = spec.buildRequests(gdprBidRequests, {refererInfo: { referer: GDPR_REQ_REFERER }})[0]; + const gdprRequest = spec.buildRequests(gdprBidRequests, { refererInfo: { referer: GDPR_REQ_REFERER } })[0]; const gdprRequestBody = gdprRequest.data; expect(gdprRequestBody.regs).to.deep.equal({ ext: {} }); expect(gdprRequestBody.user).to.deep.equal({ ext: {} }); @@ -172,7 +172,7 @@ describe('deltaprojectsBidAdapter', function() { auctionId: '1d1a030790a475', }, ]; - const request = spec.buildRequests(bidRequests, {refererInfo: { referer: BID_REQ_REFER }})[0]; + const request = spec.buildRequests(bidRequests, { refererInfo: { referer: BID_REQ_REFER } })[0]; function makeResponse() { return { body: { @@ -243,7 +243,7 @@ describe('deltaprojectsBidAdapter', function() { const noCridResponse = makeResponse(); delete noCridResponse.body.seatbid[0].bid[0].crid; const fallbackCrid = noCridResponse.body.seatbid[0].bid[0].id; - const noCridResult = Object.assign({}, expectedBid, {'creativeId': fallbackCrid}); + const noCridResult = Object.assign({}, expectedBid, { 'creativeId': fallbackCrid }); const result = spec.interpretResponse(noCridResponse, request); expect(result.length).to.equal(1); expect(result[0]).to.deep.equal(noCridResult); @@ -271,8 +271,8 @@ describe('deltaprojectsBidAdapter', function() { }); it('should keep custom properties', () => { - const customProperties = {test: 'a test message', param: {testParam: 1}}; - const expectedResult = Object.assign({}, expectedBid, {[spec.code]: customProperties}); + const customProperties = { test: 'a test message', param: { testParam: 1 } }; + const expectedResult = Object.assign({}, expectedBid, { [spec.code]: customProperties }); const response = makeResponse(); response.body.seatbid[0].bid[0].ext = customProperties; const result = spec.interpretResponse(response, request); diff --git a/test/spec/modules/dianomiBidAdapter_spec.js b/test/spec/modules/dianomiBidAdapter_spec.js index 761e12edd85..3f962ce4b9c 100644 --- a/test/spec/modules/dianomiBidAdapter_spec.js +++ b/test/spec/modules/dianomiBidAdapter_spec.js @@ -164,7 +164,7 @@ describe('Dianomi adapter', () => { }, ]; const request = JSON.parse( - spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}, ortb2: {source: {tid: 'tid'}}}).data + spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' }, ortb2: { source: { tid: 'tid' } } }).data ); assert.equal(request.source.tid, 'tid'); diff --git a/test/spec/modules/digitalMatterBidAdapter_spec.js b/test/spec/modules/digitalMatterBidAdapter_spec.js index 2627050e388..adec36a9c7b 100644 --- a/test/spec/modules/digitalMatterBidAdapter_spec.js +++ b/test/spec/modules/digitalMatterBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/digitalMatterBidAdapter'; -import {config} from '../../../src/config.js'; -import {deepClone} from '../../../src/utils.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/digitalMatterBidAdapter'; +import { config } from '../../../src/config.js'; +import { deepClone } from '../../../src/utils.js'; const bid = { 'adUnitCode': 'adUnitCode', @@ -86,7 +86,7 @@ describe('Digital Matter BidAdapter', function () { it('should send info about device', function () { config.setConfig({ - device: {w: 1920, h: 1080} + device: { w: 1920, h: 1080 } }); const request = JSON.parse(spec.buildRequests([bid], bidderRequest).data); @@ -108,10 +108,10 @@ describe('Digital Matter BidAdapter', function () { }); it('should send currency if defined', function () { - config.setConfig({currency: {adServerCurrency: 'EUR'}}); + config.setConfig({ currency: { adServerCurrency: 'EUR' } }); const request = JSON.parse(spec.buildRequests([bid], bidderRequest).data); - assert.deepEqual(request.cur, [{adServerCurrency: 'EUR'}]); + assert.deepEqual(request.cur, [{ adServerCurrency: 'EUR' }]); }); it('should pass supply chain object', function () { @@ -247,7 +247,7 @@ describe('Digital Matter BidAdapter', function () { assert.deepEqual(bids[0].width, firstResponse.width); assert.deepEqual(bids[0].height, firstResponse.height); assert.deepEqual(bids[0].dealId, undefined); - assert.deepEqual(bids[0].meta.advertiserDomains, [ 'advertiser.org' ]); + assert.deepEqual(bids[0].meta.advertiserDomains, ['advertiser.org']); assert.deepEqual(bids[1].requestId, secondResponse.bidid); assert.deepEqual(bids[1].cpm, secondResponse.cpm); @@ -258,7 +258,7 @@ describe('Digital Matter BidAdapter', function () { assert.deepEqual(bids[1].width, secondResponse.width); assert.deepEqual(bids[1].height, secondResponse.height); assert.deepEqual(bids[1].dealId, undefined); - assert.deepEqual(bids[1].meta.advertiserDomains, [ 'advertiser.org' ]); + assert.deepEqual(bids[1].meta.advertiserDomains, ['advertiser.org']); }); }); diff --git a/test/spec/modules/discoveryBidAdapter_spec.js b/test/spec/modules/discoveryBidAdapter_spec.js index fbeef8a8d7e..2b23041a69d 100644 --- a/test/spec/modules/discoveryBidAdapter_spec.js +++ b/test/spec/modules/discoveryBidAdapter_spec.js @@ -10,7 +10,7 @@ import { } from 'modules/discoveryBidAdapter.js'; import { getPageTitle, getPageDescription, getPageKeywords, getConnectionDownLink } from '../../../libraries/fpdUtils/pageInfo.js'; import * as utils from 'src/utils.js'; -import {getHLen} from '../../../libraries/navigatorData/navigatorData.js'; +import { getHLen } from '../../../libraries/navigatorData/navigatorData.js'; describe('discovery:BidAdapterTests', function () { let sandbox; diff --git a/test/spec/modules/displayioBidAdapter_spec.js b/test/spec/modules/displayioBidAdapter_spec.js index b2ab38360f6..d74cf775d73 100644 --- a/test/spec/modules/displayioBidAdapter_spec.js +++ b/test/spec/modules/displayioBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {spec} from 'modules/displayioBidAdapter.js' -import {BANNER} from '../../../src/mediaTypes.js' +import { spec } from 'modules/displayioBidAdapter.js' +import { BANNER } from '../../../src/mediaTypes.js' describe('Displayio adapter', function () { const BIDDER = 'displayio' diff --git a/test/spec/modules/dmdIdSystem_spec.js b/test/spec/modules/dmdIdSystem_spec.js index d0d8747dee9..c85ec522440 100644 --- a/test/spec/modules/dmdIdSystem_spec.js +++ b/test/spec/modules/dmdIdSystem_spec.js @@ -30,17 +30,17 @@ describe('Dmd ID System', function () { }); it('should log an error if configParams doesnot have api_key passed to getId', function () { - dmdIdSubmodule.getId({params: {}}); + dmdIdSubmodule.getId({ params: {} }); expect(logErrorStub.calledOnce).to.be.true; }); it('should log an error if configParams has invalid api_key passed into getId', function () { - dmdIdSubmodule.getId({params: {api_key: 123}}); + dmdIdSubmodule.getId({ params: { api_key: 123 } }); expect(logErrorStub.calledOnce).to.be.true; }); it('should not log an error if configParams has valid api_key passed into getId', function () { - dmdIdSubmodule.getId({params: {api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c'}}); + dmdIdSubmodule.getId({ params: { api_key: '3fdbe297-3690-4f5c-9e11-ee9186a6d77c' } }); expect(logErrorStub.calledOnce).to.be.false; }); diff --git a/test/spec/modules/docereeBidAdapter_spec.js b/test/spec/modules/docereeBidAdapter_spec.js index 6b79264f2d6..d079eaac876 100644 --- a/test/spec/modules/docereeBidAdapter_spec.js +++ b/test/spec/modules/docereeBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/docereeBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/docereeBidAdapter.js'; import { config } from '../../../src/config.js'; import * as utils from 'src/utils.js'; diff --git a/test/spec/modules/dpaiBidAdapter_spec.js b/test/spec/modules/dpaiBidAdapter_spec.js new file mode 100644 index 00000000000..f81c3aa7c95 --- /dev/null +++ b/test/spec/modules/dpaiBidAdapter_spec.js @@ -0,0 +1,511 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/dpaiBidAdapter.js'; +import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'dpai'; + +describe('DpaiBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + + } + } + + const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, + refererInfo: { + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK', + } + }, + timeout: 500 + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and key parameters present', function () { + expect(spec.isBidRequestValid(bids[0])).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests(bids, bidderRequest); + + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + + it('Returns general data valid', function () { + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys( + 'deviceWidth', + 'deviceHeight', + 'device', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax', + 'bcat', + 'badv', + 'bapp', + 'battr' + ); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); + }); + + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + }) + }); + + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + const dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + const dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + const dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + const serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + const serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); + + describe('getUserSyncs', function() { + it('Should return array of objects with proper sync config , include GDPR', function() { + const syncData = spec.getUserSyncs({}, {}, { + consentString: 'ALL', + gdprApplies: true, + }, undefined); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.drift-pixel.ai/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') + }); + it('Should return array of objects with proper sync config , include CCPA', function() { + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.drift-pixel.ai/image?pbjs=1&ccpa_consent=1---&coppa=0') + }); + it('Should return array of objects with proper sync config , include GPP', function() { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { + gppString: 'abc123', + applicableSections: [8] + }); + expect(syncData).to.be.an('array').which.is.not.empty; + expect(syncData[0]).to.be.an('object') + expect(syncData[0].type).to.be.a('string') + expect(syncData[0].type).to.equal('image') + expect(syncData[0].url).to.be.a('string') + expect(syncData[0].url).to.equal('https://sync.drift-pixel.ai/image?pbjs=1&gpp=abc123&gpp_sid=8&coppa=0') + }); + }); +}); diff --git a/test/spec/modules/driftpixelBidAdapter_spec.js b/test/spec/modules/driftpixelBidAdapter_spec.js index a7b5a164996..d1e78b2be3b 100644 --- a/test/spec/modules/driftpixelBidAdapter_spec.js +++ b/test/spec/modules/driftpixelBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/driftpixelBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/driftpixelBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; const ENDPOINT = 'https://pbjs.driftpixel.live'; @@ -49,12 +49,12 @@ defaultRequestVideo.mediaTypes = { const videoBidderRequest = { bidderCode: 'driftpixel', - bids: [{mediaTypes: {video: {}}, bidId: 'qwerty'}] + bids: [{ mediaTypes: { video: {} }, bidId: 'qwerty' }] }; const displayBidderRequest = { bidderCode: 'driftpixel', - bids: [{bidId: 'qwerty'}] + bids: [{ bidId: 'qwerty' }] }; describe('driftpixelBidAdapter', () => { @@ -110,7 +110,7 @@ describe('driftpixelBidAdapter', () => { expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); expect(request).to.have.property('floor').and.to.equal(null); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -203,7 +203,7 @@ describe('driftpixelBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -219,8 +219,8 @@ describe('driftpixelBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -272,7 +272,7 @@ describe('driftpixelBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -281,7 +281,7 @@ describe('driftpixelBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['driftpixel']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['driftpixel'] }); }); it('should interpret valid banner response', function () { @@ -302,7 +302,7 @@ describe('driftpixelBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -328,7 +328,7 @@ describe('driftpixelBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: videoBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: videoBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -344,12 +344,12 @@ describe('driftpixelBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -368,7 +368,7 @@ describe('driftpixelBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -387,7 +387,7 @@ describe('driftpixelBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -411,20 +411,20 @@ describe('driftpixelBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -432,7 +432,7 @@ describe('driftpixelBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -440,7 +440,7 @@ describe('driftpixelBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/dsaControl_spec.js b/test/spec/modules/dsaControl_spec.js index a1f8f88f23e..0522524051b 100644 --- a/test/spec/modules/dsaControl_spec.js +++ b/test/spec/modules/dsaControl_spec.js @@ -1,7 +1,7 @@ -import {addBidResponseHook, setMetaDsa, reset} from '../../../modules/dsaControl.js'; +import { addBidResponseHook, setMetaDsa, reset } from '../../../modules/dsaControl.js'; import { REJECTION_REASON } from 'src/constants.js'; -import {auctionManager} from '../../../src/auctionManager.js'; -import {AuctionIndex} from '../../../src/auctionIndex.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { AuctionIndex } from '../../../src/auctionIndex.js'; describe('DSA transparency', () => { let sandbox; @@ -25,7 +25,7 @@ describe('DSA transparency', () => { } auction = { getAuctionId: () => auctionId, - getFPD: () => ({global: fpd}) + getFPD: () => ({ global: fpd }) } sandbox.stub(auctionManager, 'index').get(() => new AuctionIndex(() => [auction])); }); @@ -46,7 +46,7 @@ describe('DSA transparency', () => { describe(`when regs.ext.dsa.dsarequired is ${required} (required)`, () => { beforeEach(() => { fpd = { - regs: {ext: {dsa: {dsarequired: required}}} + regs: { ext: { dsa: { dsarequired: required } } } }; }); @@ -55,7 +55,7 @@ describe('DSA transparency', () => { }); it('should accept bids that do', () => { - bid.meta = {dsa: {}}; + bid.meta = { dsa: {} }; expectAcceptance(); }); @@ -65,12 +65,12 @@ describe('DSA transparency', () => { }); it('should reject bids with adrender = 0 (advertiser will not render)', () => { - bid.meta = {dsa: {adrender: 0}}; + bid.meta = { dsa: { adrender: 0 } }; expectRejection(REJECTION_REASON.DSA_MISMATCH); }); it('should accept bids with adrender = 1 (advertiser will render)', () => { - bid.meta = {dsa: {adrender: 1}}; + bid.meta = { dsa: { adrender: 1 } }; expectAcceptance(); }); }); @@ -80,12 +80,12 @@ describe('DSA transparency', () => { }); it('should reject bids with adrender = 1 (advertiser will render)', () => { - bid.meta = {dsa: {adrender: 1}}; + bid.meta = { dsa: { adrender: 1 } }; expectRejection(REJECTION_REASON.DSA_MISMATCH); }); it('should accept bids with adrender = 0 (advertiser will not render)', () => { - bid.meta = {dsa: {adrender: 0}}; + bid.meta = { dsa: { adrender: 0 } }; expectAcceptance(); }) }) @@ -96,7 +96,7 @@ describe('DSA transparency', () => { beforeEach(() => { if (required != null) { fpd = { - regs: {ext: {dsa: {dsarequired: required}}} + regs: { ext: { dsa: { dsarequired: required } } } } } }); diff --git a/test/spec/modules/dspxBidAdapter_spec.js b/test/spec/modules/dspxBidAdapter_spec.js index 34bf9de292c..2064ae2e67d 100644 --- a/test/spec/modules/dspxBidAdapter_spec.js +++ b/test/spec/modules/dspxBidAdapter_spec.js @@ -3,7 +3,7 @@ import { config } from 'src/config.js'; import { spec } from 'modules/dspxBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { deepClone } from '../../../src/utils.js'; -import {BANNER} from '../../../src/mediaTypes.js'; +import { BANNER } from '../../../src/mediaTypes.js'; const ENDPOINT_URL = 'https://buyer.dspx.tv/request/'; const ENDPOINT_URL_DEV = 'https://dcbuyer.dspx.tv/request/'; @@ -282,7 +282,7 @@ describe('dspxAdapter', function () { 'dev': { 'endpoint': 'http://localhost', 'placement': '107', - 'pfilter': {'test': 1} + 'pfilter': { 'test': 1 } } }, 'mediaTypes': { @@ -316,7 +316,7 @@ describe('dspxAdapter', function () { }, gdprConsent: { consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {someData: 'value'}, + vendorData: { someData: 'value' }, gdprApplies: true } }; @@ -328,7 +328,7 @@ describe('dspxAdapter', function () { }, gdprConsent: { consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {someData: 'value'}, + vendorData: { someData: 'value' }, gdprApplies: true }, ortb2: { @@ -427,7 +427,7 @@ describe('dspxAdapter', function () { }); // bidfloor tests - const getFloorResponse = {currency: 'EUR', floor: 5}; + const getFloorResponse = { currency: 'EUR', floor: 5 }; let testBidRequest = deepClone(bidRequests[1]); let floorRequest = spec.buildRequests([testBidRequest], bidderRequestWithoutGdpr)[0]; @@ -477,7 +477,7 @@ describe('dspxAdapter', function () { }, gdprConsent: { consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', - vendorData: {someData: 'value'}, + vendorData: { someData: 'value' }, gdprApplies: true } }; @@ -516,7 +516,7 @@ describe('dspxAdapter', function () { segclass: 'v1', }, segment: [ - {id: '717'}, {id: '808'}, + { id: '717' }, { id: '808' }, ] } ] @@ -537,13 +537,13 @@ describe('dspxAdapter', function () { segment: [] }, { - segment: [{id: ''}] + segment: [{ id: '' }] }, { - segment: [{id: null}] + segment: [{ id: null }] }, { - segment: [{id: 'dummy'}, {id: '123'}] + segment: [{ id: 'dummy' }, { id: '123' }] }, { ext: { @@ -599,7 +599,7 @@ describe('dspxAdapter', function () { 'ttl': 60, 'netRevenue': true, 'zone': '6682', - 'renderer': {id: 1, url: '//player.example.com', options: {}} + 'renderer': { id: 1, url: '//player.example.com', options: {} } } }; const serverVideoResponseVastUrl = { @@ -616,7 +616,7 @@ describe('dspxAdapter', function () { 'zone': '6682', 'vastUrl': 'https://local/vasturl1', 'videoCacheKey': 'cache_123', - 'bid_appendix': {'someField': 'someValue'} + 'bid_appendix': { 'someField': 'someValue' } } }; @@ -632,7 +632,7 @@ describe('dspxAdapter', function () { ttl: 60, type: 'sspHTML', ad: '', - meta: {advertiserDomains: ['bdomain']}, + meta: { advertiserDomains: ['bdomain'] }, }, { requestId: '23beaa6af6cdde', cpm: 0.5, @@ -646,7 +646,7 @@ describe('dspxAdapter', function () { type: 'vast2', vastXml: '{"reason":7001,"status":"accepted"}', mediaType: 'video', - meta: {advertiserDomains: []}, + meta: { advertiserDomains: [] }, renderer: {} }, { requestId: '23beaa6af6cdde', @@ -662,7 +662,7 @@ describe('dspxAdapter', function () { vastUrl: 'https://local/vasturl1', videoCacheKey: 'cache_123', mediaType: 'video', - meta: {advertiserDomains: []}, + meta: { advertiserDomains: [] }, someField: 'someValue' }]; @@ -762,17 +762,17 @@ describe('dspxAdapter', function () { expect(userSync.type).to.be.equal('iframe'); }); it(`we have valid sync url for iframe`, function () { - const [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses, {consentString: 'anyString'}); + const [userSync] = spec.getUserSyncs({ iframeEnabled: true }, serverResponses, { consentString: 'anyString' }); expect(userSync.url).to.be.equal('anyIframeUrl?a=1&gdpr_consent=anyString') expect(userSync.type).to.be.equal('iframe'); }); it(`we have valid sync url for image`, function () { - const [userSync] = spec.getUserSyncs({ pixelEnabled: true }, serverResponses, {gdprApplies: true, consentString: 'anyString'}); + const [userSync] = spec.getUserSyncs({ pixelEnabled: true }, serverResponses, { gdprApplies: true, consentString: 'anyString' }); expect(userSync.url).to.be.equal('anyImageUrl?gdpr=1&gdpr_consent=anyString') expect(userSync.type).to.be.equal('image'); }); it(`we have valid sync url for image and iframe`, function () { - const userSync = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses, {gdprApplies: true, consentString: 'anyString'}); + const userSync = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, serverResponses, { gdprApplies: true, consentString: 'anyString' }); expect(userSync.length).to.be.equal(3); expect(userSync[0].url).to.be.equal('anyIframeUrl?a=1&gdpr=1&gdpr_consent=anyString') expect(userSync[0].type).to.be.equal('iframe'); diff --git a/test/spec/modules/dxkultureBidAdapter_spec.js b/test/spec/modules/dxkultureBidAdapter_spec.js index ad1adf18d02..8e6f2d78ccd 100644 --- a/test/spec/modules/dxkultureBidAdapter_spec.js +++ b/test/spec/modules/dxkultureBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec, SYNC_URL} from 'modules/dxkultureBidAdapter.js'; -import {BANNER, VIDEO} from 'src/mediaTypes.js'; +import { expect } from 'chai'; +import { spec, SYNC_URL } from 'modules/dxkultureBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; const getBannerRequest = () => { return { @@ -20,7 +20,7 @@ const getBannerRequest = () => { mediaTypes: { banner: { sizes: [ - [ 300, 250 ], + [300, 250], ] } }, @@ -421,7 +421,7 @@ describe('dxkultureBidAdapter', function() { beforeEach(function() { bidderBannerRequest = getBannerRequest(); - mockBidderRequest = {refererInfo: {}}; + mockBidderRequest = { refererInfo: {} }; bidRequestsWithMediaTypes = [{ bidder: 'dxkulture', @@ -539,7 +539,7 @@ describe('dxkultureBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; @@ -574,32 +574,36 @@ describe('dxkultureBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; }); it('should return no bids if the response "nurl" and "adm" are missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - price: 6.01 + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + price: 6.01 + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); it('should return no bids if the response "price" is missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - adm: '' + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + adm: '' + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); @@ -619,13 +623,13 @@ describe('dxkultureBidAdapter', function() { expect(opts).to.be.an('array').that.is.empty; }); it('returns non if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('iframe sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('iframe'); @@ -633,7 +637,7 @@ describe('dxkultureBidAdapter', function() { }); it('pixel sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('image'); @@ -641,7 +645,7 @@ describe('dxkultureBidAdapter', function() { }); it('all sync enabled should prioritize iframe', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); }); diff --git a/test/spec/modules/dxtechBidAdapter_spec.js b/test/spec/modules/dxtechBidAdapter_spec.js index 216610e8246..758aea40d4a 100644 --- a/test/spec/modules/dxtechBidAdapter_spec.js +++ b/test/spec/modules/dxtechBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/dxtechBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/dxtechBidAdapter.js'; const getBannerRequest = () => { return { @@ -19,7 +19,7 @@ const getBannerRequest = () => { mediaTypes: { banner: { sizes: [ - [ 300, 250 ], + [300, 250], ] } }, @@ -393,7 +393,7 @@ describe('dxtechBidAdapter', function() { let mockBidderRequest; beforeEach(function() { - mockBidderRequest = {refererInfo: {}}; + mockBidderRequest = { refererInfo: {} }; bidRequestsWithMediaTypes = [{ bidder: 'dxtech', @@ -494,7 +494,7 @@ describe('dxtechBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; @@ -530,32 +530,36 @@ describe('dxtechBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; }); it('should return no bids if the response "nurl" and "adm" are missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - price: 6.01 + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + price: 6.01 + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); it('should return no bids if the response "price" is missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - adm: '' + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + adm: '' + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); @@ -575,12 +579,12 @@ describe('dxtechBidAdapter', function() { }); it('returns none if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('iframe sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('iframe'); @@ -588,7 +592,7 @@ describe('dxtechBidAdapter', function() { }); it('pixel sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('image'); @@ -596,7 +600,7 @@ describe('dxtechBidAdapter', function() { }); it('all sync enabled should prioritize iframe', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [bidderResponse]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); }); diff --git a/test/spec/modules/eids_spec.js b/test/spec/modules/eids_spec.js index 17d2b5161b0..9b151835aca 100644 --- a/test/spec/modules/eids_spec.js +++ b/test/spec/modules/eids_spec.js @@ -1,4 +1,4 @@ -import {createEidsArray} from 'modules/userId/eids.js'; +import { createEidsArray } from 'modules/userId/eids.js'; describe('eids array generation for known sub-modules', function () { it('pubProvidedId', function () { diff --git a/test/spec/modules/eightPodAnalyticsAdapter_spec.js b/test/spec/modules/eightPodAnalyticsAdapter_spec.js index 3f798344d0d..5d986125bda 100644 --- a/test/spec/modules/eightPodAnalyticsAdapter_spec.js +++ b/test/spec/modules/eightPodAnalyticsAdapter_spec.js @@ -132,7 +132,7 @@ describe('eightPodAnalyticAdapter', function() { }); it('should add event to the queue', function() { - getContextStub.returns({adUnitCode: {}}); + getContextStub.returns({ adUnitCode: {} }); const event1 = { detail: { diff --git a/test/spec/modules/eightPodBidAdapter_spec.js b/test/spec/modules/eightPodBidAdapter_spec.js index 0259f782fe2..67ef98b2117 100644 --- a/test/spec/modules/eightPodBidAdapter_spec.js +++ b/test/spec/modules/eightPodBidAdapter_spec.js @@ -81,7 +81,8 @@ describe('eightPodBidAdapter', function () { dnt: 1, js: 1, } - } } + } + } }) it('should return an empty array when no bid requests', function () { diff --git a/test/spec/modules/emtvBidAdapter_spec.js b/test/spec/modules/emtvBidAdapter_spec.js index 0e91f3fa719..a75522607c1 100644 --- a/test/spec/modules/emtvBidAdapter_spec.js +++ b/test/spec/modules/emtvBidAdapter_spec.js @@ -485,7 +485,7 @@ describe('EMTVBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -494,9 +494,7 @@ describe('EMTVBidAdapter', function () { expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0`) }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -505,7 +503,7 @@ describe('EMTVBidAdapter', function () { expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`) }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/enrichmentLiftMeasurement_spec.js b/test/spec/modules/enrichmentLiftMeasurement_spec.js index 4473c851fbf..e144eb3d3c3 100644 --- a/test/spec/modules/enrichmentLiftMeasurement_spec.js +++ b/test/spec/modules/enrichmentLiftMeasurement_spec.js @@ -1,6 +1,6 @@ import { expect } from "chai"; import { getCalculatedSubmodules, internals, init, reset, storeSplitsMethod, storeTestConfig, suppressionMethod, getStoredTestConfig, compareConfigs, STORAGE_KEY } from "../../../modules/enrichmentLiftMeasurement/index.js"; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; import { config } from "../../../src/config.js" import { isInteger } from "../../../src/utils.js"; import { ACTIVITY_ENRICH_EIDS } from "../../../src/activities/activities.js"; @@ -35,9 +35,11 @@ describe('enrichmentLiftMeasurement', () => { const mathRandomStub = sinon.stub(Math, 'random').callsFake(() => { return fixedRandoms[callIndex++]; }); - config.setConfig({ enrichmentLiftMeasurement: { - modules: modulesConfig - }}); + config.setConfig({ + enrichmentLiftMeasurement: { + modules: modulesConfig + } + }); const results = []; for (let i = 0; i < TEST_SAMPLE_SIZE; i++) { @@ -45,7 +47,7 @@ describe('enrichmentLiftMeasurement', () => { } modulesConfig.forEach((idSystem) => { const passedIdSystemsCount = results.filter((execution) => { - const item = execution.find(({name}) => idSystem.name === name) + const item = execution.find(({ name }) => idSystem.name === name) return item?.enabled }).length const marginOfError = Number(Math.abs(passedIdSystemsCount / TEST_SAMPLE_SIZE - idSystem.percentage).toFixed(2)); @@ -61,14 +63,16 @@ describe('enrichmentLiftMeasurement', () => { [suppressionMethod.SUBMODULES]: true }).forEach(([method, value]) => { it(method, () => { - config.setConfig({ enrichmentLiftMeasurement: { - suppression: method, - modules: [ - { name: 'idSystem', percentage: 0 } - ] - }}); + config.setConfig({ + enrichmentLiftMeasurement: { + suppression: method, + modules: [ + { name: 'idSystem', percentage: 0 } + ] + } + }); init(); - expect(isActivityAllowed(ACTIVITY_ENRICH_EIDS, activityParams(MODULE_TYPE_UID, 'idSystem', {init: false}))).to.eql(value); + expect(isActivityAllowed(ACTIVITY_ENRICH_EIDS, activityParams(MODULE_TYPE_UID, 'idSystem', { init: false }))).to.eql(value); }); }); }); @@ -84,13 +88,15 @@ describe('enrichmentLiftMeasurement', () => { beforeEach(() => { getCalculatedSubmodulesStub = sinon.stub(internals, 'getCalculatedSubmodules'); - config.setConfig({ enrichmentLiftMeasurement: { - testRun: TEST_RUN_ID, - storeSplits: storeSplitsMethod.SESSION_STORAGE, - modules: [ - { name: 'idSystem', percentage: 1 } - ] - }}); + config.setConfig({ + enrichmentLiftMeasurement: { + testRun: TEST_RUN_ID, + storeSplits: storeSplitsMethod.SESSION_STORAGE, + modules: [ + { name: 'idSystem', percentage: 1 } + ] + } + }); }); afterEach(() => { @@ -115,7 +121,7 @@ describe('enrichmentLiftMeasurement', () => { }); it('should store config if not present', () => { - const stubCalculation = mockConfig.map(module => ({...module, percentage: 0.1})); + const stubCalculation = mockConfig.map(module => ({ ...module, percentage: 0.1 })); getCalculatedSubmodulesStub.returns(stubCalculation); const fakeStorageManager = { sessionStorageIsEnabled: () => true, @@ -125,12 +131,12 @@ describe('enrichmentLiftMeasurement', () => { init(fakeStorageManager); sinon.assert.calledOnce(fakeStorageManager.setDataInSessionStorage); sinon.assert.calledOnce(getCalculatedSubmodulesStub); - const expectedArg = {testRun: TEST_RUN_ID, modules: stubCalculation}; + const expectedArg = { testRun: TEST_RUN_ID, modules: stubCalculation }; expect(fakeStorageManager.setDataInSessionStorage.getCall(0).args[1]).to.deep.eql(JSON.stringify(expectedArg)); }); it('should update config if present is different', () => { - const stubCalculation = mockConfig.map(module => ({...module, percentage: 0.1})); + const stubCalculation = mockConfig.map(module => ({ ...module, percentage: 0.1 })); getCalculatedSubmodulesStub.returns(stubCalculation); const previousTestConfig = { modules: mockConfig, @@ -141,11 +147,13 @@ describe('enrichmentLiftMeasurement', () => { getDataFromSessionStorage: sinon.stub().returns(JSON.stringify(previousTestConfig)), setDataInSessionStorage: sinon.stub() }; - config.setConfig({ enrichmentLiftMeasurement: { - testRun: TEST_RUN_ID, - storeSplits: storeSplitsMethod.SESSION_STORAGE, - modules: mockConfig.map(module => ({...module, percentage: 0.1})) - }}); + config.setConfig({ + enrichmentLiftMeasurement: { + testRun: TEST_RUN_ID, + storeSplits: storeSplitsMethod.SESSION_STORAGE, + modules: mockConfig.map(module => ({ ...module, percentage: 0.1 })) + } + }); init(fakeStorageManager); @@ -161,20 +169,22 @@ describe('enrichmentLiftMeasurement', () => { url: 'https://localhost:9999/endpoint', analyticsType: 'endpoint' }); - config.setConfig({ enrichmentLiftMeasurement: { - modules: mockConfig, - testRun: TEST_RUN_ID, - storeSplits: storeSplitsMethod.PAGE - }}); + config.setConfig({ + enrichmentLiftMeasurement: { + modules: mockConfig, + testRun: TEST_RUN_ID, + storeSplits: storeSplitsMethod.PAGE + } + }); init(); const eventType = EVENTS.BID_WON; - adapter.track({eventType}); + adapter.track({ eventType }); const result = JSON.parse(server.requests[0].requestBody); - sinon.assert.match(result, {labels: {[TEST_RUN_ID]: mockConfig}, eventType}); + sinon.assert.match(result, { labels: { [TEST_RUN_ID]: mockConfig }, eventType }); disableAjaxForAnalytics(); }); @@ -227,15 +237,15 @@ describe('enrichmentLiftMeasurement', () => { const oldConfig = { testRun: 'AB1', modules: [ - {name: 'idSystem1', percentage: 1.0, enabled: true}, - {name: 'idSystem2', percentage: 0.3, enabled: false}, + { name: 'idSystem1', percentage: 1.0, enabled: true }, + { name: 'idSystem2', percentage: 0.3, enabled: false }, ] } const newConfig = { testRun: 'AB1', modules: [ - {name: 'idSystem2', percentage: 0.3}, - {name: 'idSystem1', percentage: 1.0}, + { name: 'idSystem2', percentage: 0.3 }, + { name: 'idSystem1', percentage: 1.0 }, ] } expect(compareConfigs(newConfig, oldConfig)).to.eql(true); @@ -245,15 +255,15 @@ describe('enrichmentLiftMeasurement', () => { const oldConfig = { testRun: 'AB1', modules: [ - {name: 'idSystem1', percentage: 1.0, enabled: true}, - {name: 'idSystem2', percentage: 0.3, enabled: false}, + { name: 'idSystem1', percentage: 1.0, enabled: true }, + { name: 'idSystem2', percentage: 0.3, enabled: false }, ] } const newConfig = { testRun: 'AB2', modules: [ - {name: 'idSystem2', percentage: 0.3}, - {name: 'idSystem1', percentage: 1.0}, + { name: 'idSystem2', percentage: 0.3 }, + { name: 'idSystem1', percentage: 1.0 }, ] } expect(compareConfigs(newConfig, oldConfig)).to.eql(false); diff --git a/test/spec/modules/eplanningBidAdapter_spec.js b/test/spec/modules/eplanningBidAdapter_spec.js index 15f05fc12a5..04e742315d1 100644 --- a/test/spec/modules/eplanningBidAdapter_spec.js +++ b/test/spec/modules/eplanningBidAdapter_spec.js @@ -2,12 +2,12 @@ import { expect } from 'chai'; import { spec, storage } from 'modules/eplanningBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {init, getIds} from 'modules/userId/index.js'; +import { init, getIds } from 'modules/userId/index.js'; import * as utils from 'src/utils.js'; -import {hook} from '../../../src/hook.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { hook } from '../../../src/hook.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; import { makeSlot } from '../integration/faker/googletag.js'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; import { internal, resetWinDimensions } from '../../../src/utils.js'; describe('E-Planning Adapter', function () { @@ -1138,7 +1138,7 @@ describe('E-Planning Adapter', function () { return element; }, observe: (element) => { - intersectionCallback([{'target': {'id': element.id}, 'isIntersecting': params[element.id].isIntersecting, 'intersectionRatio': params[element.id].ratio, 'boundingClientRect': {'width': params[element.id].width, 'height': params[element.id].height}}]); + intersectionCallback([{ 'target': { 'id': element.id }, 'isIntersecting': params[element.id].isIntersecting, 'intersectionRatio': params[element.id].ratio, 'boundingClientRect': { 'width': params[element.id].width, 'height': params[element.id].height } }]); }, }; }; @@ -1278,7 +1278,7 @@ describe('E-Planning Adapter', function () { let respuesta; beforeEach(function () { createElementVisible(); - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200 } }); }); it('when you have a render', function() { respuesta = spec.buildRequests(bidRequests, bidderRequest); @@ -1316,7 +1316,7 @@ describe('E-Planning Adapter', function () { let respuesta; beforeEach(function () { createElementOutOfView(); - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200 } }); }); it('when you have a render', function() { @@ -1342,7 +1342,7 @@ describe('E-Planning Adapter', function () { let respuesta; it('should register visibility with more than 50%', function() { createPartiallyVisibleElement(); - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 0.6, 'isIntersecting': true, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 0.6, 'isIntersecting': true, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequests, bidderRequest); clock.tick(1005); @@ -1351,7 +1351,7 @@ describe('E-Planning Adapter', function () { }); it('you should not register visibility with less than 50%', function() { createPartiallyInvisibleElement(); - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 0.4, 'isIntersecting': true, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 0.4, 'isIntersecting': true, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequests, bidderRequest); clock.tick(1005); @@ -1366,7 +1366,7 @@ describe('E-Planning Adapter', function () { const divId = 'div-gpt-ad-123'; createPartiallyVisibleElement(divId); window.googletag.pubads().setSlots([makeSlot({ code, divId })]); - setIntersectionObserverMock({[divId]: {'ratio': 0.6, 'isIntersecting': true, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [divId]: { 'ratio': 0.6, 'isIntersecting': true, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequests, bidderRequest); clock.tick(1005); @@ -1381,7 +1381,7 @@ describe('E-Planning Adapter', function () { }); it('if the width is zero but the height is within the range', function() { element.style.width = '0px'; - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 0.4, 'isIntersecting': true, 'width': 200, 'height': 200}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 0.4, 'isIntersecting': true, 'width': 200, 'height': 200 } }); spec.buildRequests(bidRequests, bidderRequest) clock.tick(1005); @@ -1390,7 +1390,7 @@ describe('E-Planning Adapter', function () { }); it('if the height is zero but the width is within the range', function() { element.style.height = '0px'; - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 1, 'isIntersecting': true, 'width': 500, 'height': 0}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 1, 'isIntersecting': true, 'width': 500, 'height': 0 } }); spec.buildRequests(bidRequests, bidderRequest) clock.tick(1005); @@ -1400,7 +1400,7 @@ describe('E-Planning Adapter', function () { it('if both are zero', function() { element.style.height = '0px'; element.style.width = '0px'; - setIntersectionObserverMock({[ADUNIT_CODE_VIEW]: {'ratio': 1, 'isIntersecting': true, 'width': 0, 'height': 0}}); + setIntersectionObserverMock({ [ADUNIT_CODE_VIEW]: { 'ratio': 1, 'isIntersecting': true, 'width': 0, 'height': 0 } }); spec.buildRequests(bidRequests, bidderRequest) clock.tick(1005); @@ -1439,9 +1439,9 @@ describe('E-Planning Adapter', function () { createElementVisible(ADUNIT_CODE_VIEW2); createElementVisible(ADUNIT_CODE_VIEW3); setIntersectionObserverMock({ - [ADUNIT_CODE_VIEW]: {'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW2]: {'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW3]: {'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200} + [ADUNIT_CODE_VIEW]: { 'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW2]: { 'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW3]: { 'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); clock.tick(1005); @@ -1456,9 +1456,9 @@ describe('E-Planning Adapter', function () { createElementOutOfView(ADUNIT_CODE_VIEW2); createElementOutOfView(ADUNIT_CODE_VIEW3); setIntersectionObserverMock({ - [ADUNIT_CODE_VIEW]: {'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW2]: {'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW3]: {'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200} + [ADUNIT_CODE_VIEW]: { 'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW2]: { 'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW3]: { 'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); clock.tick(1005); @@ -1474,9 +1474,9 @@ describe('E-Planning Adapter', function () { createElementOutOfView(ADUNIT_CODE_VIEW2); createElementOutOfView(ADUNIT_CODE_VIEW3); setIntersectionObserverMock({ - [ADUNIT_CODE_VIEW]: {'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW2]: {'ratio': 0.3, 'isIntersecting': true, 'width': 200, 'height': 200}, - [ADUNIT_CODE_VIEW3]: {'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200} + [ADUNIT_CODE_VIEW]: { 'ratio': 1, 'isIntersecting': true, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW2]: { 'ratio': 0.3, 'isIntersecting': true, 'width': 200, 'height': 200 }, + [ADUNIT_CODE_VIEW3]: { 'ratio': 0, 'isIntersecting': false, 'width': 200, 'height': 200 } }); respuesta = spec.buildRequests(bidRequestMultiple, bidderRequest); clock.tick(1005); diff --git a/test/spec/modules/escalaxBidAdapter_spec.js b/test/spec/modules/escalaxBidAdapter_spec.js index 8a441a04b0b..dcabe3b1686 100644 --- a/test/spec/modules/escalaxBidAdapter_spec.js +++ b/test/spec/modules/escalaxBidAdapter_spec.js @@ -180,7 +180,7 @@ describe('escalaxAdapter', function () { }); it('should send the CCPA data in the request', async function () { - const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({...bidderRequest, ...{uspConsent: '1YYY'}})); + const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({ ...bidderRequest, ...{ uspConsent: '1YYY' } })); expect(serverRequest.data.regs.ext.us_privacy).to.equal('1YYY'); }); }); diff --git a/test/spec/modules/eskimiBidAdapter_spec.js b/test/spec/modules/eskimiBidAdapter_spec.js index a6c987aa72e..03d514b056f 100644 --- a/test/spec/modules/eskimiBidAdapter_spec.js +++ b/test/spec/modules/eskimiBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/eskimiBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/eskimiBidAdapter.js'; import * as utils from 'src/utils'; const BANNER_BID = { @@ -165,8 +165,8 @@ describe('Eskimi bid adapter', function () { it('should properly forward ORTB blocking params', function () { let bid = utils.deepClone(BANNER_BID); bid = utils.mergeDeep(bid, { - params: {bcat: ['IAB1-1'], badv: ['example.com'], bapp: ['com.example']}, - mediaTypes: {banner: {battr: [1]}} + params: { bcat: ['IAB1-1'], badv: ['example.com'], bapp: ['com.example'] }, + mediaTypes: { banner: { battr: [1] } } }); const [request] = spec.buildRequests([bid], BIDDER_REQUEST); @@ -253,7 +253,7 @@ describe('Eskimi bid adapter', function () { const [request] = spec.buildRequests([bid], BIDDER_REQUEST); const response = utils.deepClone(BANNER_BID_RESPONSE); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.be.an('array').that.is.not.empty; expect(bids[0].mediaType).to.equal('banner'); @@ -274,7 +274,7 @@ describe('Eskimi bid adapter', function () { const bid = utils.deepClone(BANNER_BID); const request = spec.buildRequests([bid], BIDDER_REQUEST)[0]; - const EMPTY_RESP = Object.assign({}, BANNER_BID_RESPONSE, {'body': {}}); + const EMPTY_RESP = Object.assign({}, BANNER_BID_RESPONSE, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, request); expect(bids).to.be.empty; }); @@ -285,7 +285,7 @@ describe('Eskimi bid adapter', function () { const bid = utils.deepClone(VIDEO_BID); const [request] = spec.buildRequests([bid], BIDDER_REQUEST); - const bids = spec.interpretResponse({body: VIDEO_BID_RESPONSE}, request); + const bids = spec.interpretResponse({ body: VIDEO_BID_RESPONSE }, request); expect(bids).to.be.an('array').that.is.not.empty; expect(bids[0].mediaType).to.equal('video'); diff --git a/test/spec/modules/etargetBidAdapter_spec.js b/test/spec/modules/etargetBidAdapter_spec.js index c00856d4f57..d53629443ca 100644 --- a/test/spec/modules/etargetBidAdapter_spec.js +++ b/test/spec/modules/etargetBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {assert, expect} from 'chai'; -import {spec} from 'modules/etargetBidAdapter.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/etargetBidAdapter.js'; import { BANNER, VIDEO } from 'src/mediaTypes.js'; import { deepClone } from 'src/utils.js'; @@ -112,7 +112,7 @@ describe('etarget adapter', function () { describe('gdpr', function () { it('should send GDPR Consent data to etarget if gdprApplies', function () { const resultBids = JSON.parse(JSON.stringify(bids[0])); - const request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: true, consentString: 'concentDataString'}}); + const request = spec.buildRequests([bids[0]], { gdprConsent: { gdprApplies: true, consentString: 'concentDataString' } }); const parsedUrl = parseUrl(request.url).query; assert.equal(parsedUrl.gdpr, 'true'); @@ -121,19 +121,19 @@ describe('etarget adapter', function () { it('should not send GDPR Consent data to etarget if gdprApplies is false or undefined', function () { const resultBids = JSON.parse(JSON.stringify(bids[0])); - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: false, consentString: 'concentDataString'}}); + let request = spec.buildRequests([bids[0]], { gdprConsent: { gdprApplies: false, consentString: 'concentDataString' } }); const parsedUrl = parseUrl(request.url).query; assert.ok(!parsedUrl.gdpr); assert.ok(!parsedUrl.gdpr_consent); - request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: undefined, consentString: 'concentDataString'}}); + request = spec.buildRequests([bids[0]], { gdprConsent: { gdprApplies: undefined, consentString: 'concentDataString' } }); assert.ok(!parsedUrl.gdpr); assert.ok(!parsedUrl.gdpr_consent); }); it('should return GDPR Consent data with request data', function () { - let request = spec.buildRequests([bids[0]], {gdprConsent: {gdprApplies: true, consentString: 'concentDataString'}}); + let request = spec.buildRequests([bids[0]], { gdprConsent: { gdprApplies: true, consentString: 'concentDataString' } }); assert.deepEqual(request.gdpr, { gdpr: true, @@ -200,7 +200,7 @@ describe('etarget adapter', function () { }); it('should set mediaType on bid response', function () { - const expected = [ BANNER, BANNER, BANNER, VIDEO, VIDEO ]; + const expected = [BANNER, BANNER, BANNER, VIDEO, VIDEO]; const result = spec.interpretResponse(serverResponse, bidRequest); for (let i = 0; i < result.length; i++) { assert.equal(result[i].mediaType, expected[i]); @@ -283,7 +283,7 @@ describe('etarget adapter', function () { beforeEach(function () { const sizes = [[250, 300], [300, 250], [300, 600]]; const placementCode = ['div-01', 'div-02', 'div-03', 'div-04', 'div-05']; - const params = [{refid: 1, country: 1, url: 'some// there'}, {refid: 2, country: 1, someVar: 'someValue', pt: 'gross'}, {refid: 3, country: 1, pdom: 'home'}, {refid: 5, country: 1, pt: 'net'}, {refid: 6, country: 1, pt: 'gross'}]; + const params = [{ refid: 1, country: 1, url: 'some// there' }, { refid: 2, country: 1, someVar: 'someValue', pt: 'gross' }, { refid: 3, country: 1, pdom: 'home' }, { refid: 5, country: 1, pt: 'net' }, { refid: 6, country: 1, pt: 'gross' }]; bids = [ { adUnitCode: placementCode[0], diff --git a/test/spec/modules/euidIdSystem_spec.js b/test/spec/modules/euidIdSystem_spec.js index dec68af7025..cb63618fdaa 100644 --- a/test/spec/modules/euidIdSystem_spec.js +++ b/test/spec/modules/euidIdSystem_spec.js @@ -1,13 +1,13 @@ -import {attachIdSystem, coreStorage, init, setSubmoduleRegistry} from 'modules/userId/index.js'; -import {config} from 'src/config.js'; -import {euidIdSubmodule} from 'modules/euidIdSystem.js'; +import { attachIdSystem, coreStorage, init, setSubmoduleRegistry } from 'modules/userId/index.js'; +import { config } from 'src/config.js'; +import { euidIdSubmodule } from 'modules/euidIdSystem.js'; import 'modules/consentManagementTcf.js'; -import {requestBids} from '../../../src/prebid.js'; -import {apiHelpers, cookieHelpers, runAuction, setGdprApplies} from './uid2IdSystem_helpers.js'; -import {hook} from 'src/hook.js'; -import {uninstall as uninstallTcfControl} from 'modules/tcfControl.js'; -import {server} from 'test/mocks/xhr'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { requestBids } from '../../../src/prebid.js'; +import { apiHelpers, cookieHelpers, runAuction, setGdprApplies } from './uid2IdSystem_helpers.js'; +import { hook } from 'src/hook.js'; +import { uninstall as uninstallTcfControl } from 'modules/tcfControl.js'; +import { server } from 'test/mocks/xhr'; +import { createEidsArray } from '../../../modules/userId/eids.js'; const expect = require('chai').expect; @@ -21,12 +21,12 @@ const legacyToken = 'legacy-advertising-token'; const refreshedToken = 'refreshed-advertising-token'; const auctionDelayMs = 10; -const makeEuidIdentityContainer = (token) => ({euid: {id: token}}); -const makeEuidOptoutContainer = (token) => ({euid: {optout: true}}); +const makeEuidIdentityContainer = (token) => ({ euid: { id: token } }); +const makeEuidOptoutContainer = (token) => ({ euid: { optout: true } }); const useLocalStorage = true; const makePrebidConfig = (params = null, extraSettings = {}, debug = false) => ({ - userSync: { auctionDelay: auctionDelayMs, userIds: [{name: 'euid', params: {storage: useLocalStorage ? 'localStorage' : 'cookie', ...params}, ...extraSettings}] }, debug + userSync: { auctionDelay: auctionDelayMs, userIds: [{ name: 'euid', params: { storage: useLocalStorage ? 'localStorage' : 'cookie', ...params }, ...extraSettings }] }, debug }); const cstgConfigParams = { serverPublicKey: 'UID2-X-L-24B8a/eLYBmRkXA9yPgRZt+ouKbXewG2OPs23+ov3JC8mtYJBCx6AxGwJ4MlwUcguebhdDp2CvzsCgS9ogwwGA==', subscriptionId: 'subscription-id' } @@ -90,7 +90,7 @@ describe('EUID module', function() { it('When a server-only token value is provided in config, it is available to the auction.', async function() { setGdprApplies(true); - config.setConfig(makePrebidConfig(null, {value: makeEuidIdentityContainer(initialToken)})); + config.setConfig(makePrebidConfig(null, { value: makeEuidIdentityContainer(initialToken) })); const bid = await runAuction(); expectToken(bid, initialToken); }); @@ -98,7 +98,7 @@ describe('EUID module', function() { it('When a server-only token is provided in the module storage cookie but consent is not available, it is not available to the auction.', async function() { setGdprApplies(); coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry()); - config.setConfig({userSync: {auctionDelay: auctionDelayMs, userIds: [{name: 'euid'}]}}); + config.setConfig({ userSync: { auctionDelay: auctionDelayMs, userIds: [{ name: 'euid' }] } }); const bid = await runAuction(); expectNoIdentity(bid); }); @@ -106,7 +106,7 @@ describe('EUID module', function() { it('When a server-only token is provided in the module storage cookie, it is available to the auction.', async function() { setGdprApplies(true); coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry()); - config.setConfig({userSync: {auctionDelay: auctionDelayMs, userIds: [{name: 'euid'}]}}); + config.setConfig({ userSync: { auctionDelay: auctionDelayMs, userIds: [{ name: 'euid' }] } }); const bid = await runAuction(); expectToken(bid, legacyToken); }) @@ -114,7 +114,7 @@ describe('EUID module', function() { it('When a valid response body is provided in config, it is available to the auction', async function() { setGdprApplies(true); const euidToken = apiHelpers.makeTokenResponse(initialToken, false, false); - config.setConfig(makePrebidConfig({euidToken})); + config.setConfig(makePrebidConfig({ euidToken })); const bid = await runAuction(); expectToken(bid, initialToken); }) @@ -123,7 +123,7 @@ describe('EUID module', function() { setGdprApplies(true); const euidToken = apiHelpers.makeTokenResponse(initialToken, false, false); cookieHelpers.setPublisherCookie(publisherCookieName, euidToken); - config.setConfig(makePrebidConfig({euidCookie: publisherCookieName})); + config.setConfig(makePrebidConfig({ euidCookie: publisherCookieName })); const bid = await runAuction(); expectToken(bid, initialToken); }) @@ -131,7 +131,7 @@ describe('EUID module', function() { it('When an expired token is provided in config, it calls the API.', async function () { setGdprApplies(true); const euidToken = apiHelpers.makeTokenResponse(initialToken, true, true); - config.setConfig(makePrebidConfig({euidToken})); + config.setConfig(makePrebidConfig({ euidToken })); await runAuction(); expect(server.requests[0]?.url).to.have.string('https://prod.euid.eu/'); }); @@ -140,7 +140,7 @@ describe('EUID module', function() { setGdprApplies(true); const euidToken = apiHelpers.makeTokenResponse(initialToken, true, true); configureEuidResponse(200, makeSuccessResponseBody(refreshedToken)); - config.setConfig(makePrebidConfig({euidToken})); + config.setConfig(makePrebidConfig({ euidToken })); apiHelpers.respondAfterDelay(1, server); const bid = await runAuction(); expectToken(bid, refreshedToken); @@ -175,7 +175,7 @@ describe('EUID module', function() { }); it('euid', function() { const userId = { - euid: {'id': 'Sample_AD_Token'} + euid: { 'id': 'Sample_AD_Token' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); diff --git a/test/spec/modules/experianRtdProvider_spec.js b/test/spec/modules/experianRtdProvider_spec.js index 556851e3582..e02f036885c 100644 --- a/test/spec/modules/experianRtdProvider_spec.js +++ b/test/spec/modules/experianRtdProvider_spec.js @@ -9,7 +9,7 @@ import { import { getStorageManager } from '../../../src/storageManager.js'; import { MODULE_TYPE_RTD } from '../../../src/activities/modules.js'; import { safeJSONParse, timestamp } from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; describe('Experian realtime module', () => { const sandbox = sinon.createSandbox(); @@ -114,7 +114,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -152,7 +152,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -168,7 +168,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -191,7 +191,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -215,7 +215,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -239,7 +239,7 @@ describe('Experian realtime module', () => { bidder: {} } } - const userConsent = {gdpr: {}, uspConsent: {}} + const userConsent = { gdpr: {}, uspConsent: {} } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic', 'sovrn'] } } const dataEnvelopeSpy = sandbox.spy(experianRtdObj, 'requestDataEnvelope') const alterBidsSpy = sandbox.spy(experianRtdObj, 'alterBids') @@ -283,10 +283,12 @@ describe('Experian realtime module', () => { } const moduleConfig = { params: { accountId: 'ZylatYg', bidders: ['pubmatic'] } } experianRtdObj.alterBids(bidsConfig, moduleConfig); - expect(bidsConfig.ortb2Fragments.bidder).to.deep.equal({pubmatic: { - experianRtidKey: 'pubmatic-encryption-key-1', - experianRtidData: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==' - }}) + expect(bidsConfig.ortb2Fragments.bidder).to.deep.equal({ + pubmatic: { + experianRtidKey: 'pubmatic-encryption-key-1', + experianRtidData: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==' + } + }) }) }) describe('data envelope is missing bidders from config', () => { @@ -318,7 +320,8 @@ describe('Experian realtime module', () => { sovrn: { experianRtidKey: 'sovrn-encryption-key-1', experianRtidData: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==' - }}) + } + }) }) }) }) @@ -334,7 +337,7 @@ describe('Experian realtime module', () => { ) expect(requests[0].url).to.equal('https://rtid.tapad.com/acc/ZylatYg/ids?gdpr=0&gdpr_consent=wow&us_privacy=1YYY') - expect(safeJSONParse(storage.getDataFromLocalStorage(EXPERIAN_RTID_DATA_KEY, null))).to.deep.equal([{bidder: 'pubmatic', data: {key: 'pubmatic-encryption-key-1', data: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg=='}}, {bidder: 'sovrn', data: {key: 'sovrn-encryption-key-1', data: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg=='}}]) + expect(safeJSONParse(storage.getDataFromLocalStorage(EXPERIAN_RTID_DATA_KEY, null))).to.deep.equal([{ bidder: 'pubmatic', data: { key: 'pubmatic-encryption-key-1', data: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==' } }, { bidder: 'sovrn', data: { key: 'sovrn-encryption-key-1', data: 'IkhlbGxvLCB3b3JsZC4gSGVsbG8sIHdvcmxkLiBIZWxsbywgd29ybGQuIg==' } }]) expect(storage.getDataFromLocalStorage(EXPERIAN_RTID_STALE_KEY)).to.equal('2023-06-01T00:00:00') expect(storage.getDataFromLocalStorage(EXPERIAN_RTID_EXPIRATION_KEY)).to.equal('2023-06-03T00:00:00') }) diff --git a/test/spec/modules/fabrickIdSystem_spec.js b/test/spec/modules/fabrickIdSystem_spec.js index 7f5227a142b..33ae99c45c0 100644 --- a/test/spec/modules/fabrickIdSystem_spec.js +++ b/test/spec/modules/fabrickIdSystem_spec.js @@ -1,7 +1,7 @@ import * as utils from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; -import {fabrickIdSubmodule, appendUrl} from 'modules/fabrickIdSystem.js'; +import { fabrickIdSubmodule, appendUrl } from 'modules/fabrickIdSystem.js'; const defaultConfigParams = { apiKey: '123', @@ -9,7 +9,7 @@ const defaultConfigParams = { p: ['def', 'hij'], url: 'http://localhost:9999/test/mocks/fabrickId.json?' }; -const responseHeader = {'Content-Type': 'application/json'} +const responseHeader = { 'Content-Type': 'application/json' } describe('Fabrick ID System', function() { let logErrorStub; diff --git a/test/spec/modules/fanBidAdapter_spec.js b/test/spec/modules/fanBidAdapter_spec.js index 04fbf5d7fb6..7ebbee45924 100644 --- a/test/spec/modules/fanBidAdapter_spec.js +++ b/test/spec/modules/fanBidAdapter_spec.js @@ -330,7 +330,7 @@ describe('freedomadnetworkAdapter', function() { meta: { libertas: { pxl: [ - {url: 'https://pxl.nurl/track?bid=req456', type: 0} + { url: 'https://pxl.nurl/track?bid=req456', type: 0 } ], }, }, diff --git a/test/spec/modules/feedadBidAdapter_spec.js b/test/spec/modules/feedadBidAdapter_spec.js index dbabb4dd587..4c5f637b15e 100644 --- a/test/spec/modules/feedadBidAdapter_spec.js +++ b/test/spec/modules/feedadBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/feedadBidAdapter.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; -import {server} from 'test/mocks/xhr.js'; +import { expect } from 'chai'; +import { spec } from 'modules/feedadBidAdapter.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; +import { server } from 'test/mocks/xhr.js'; const CODE = 'feedad'; const EXPECTED_ADAPTER_VERSION = '1.0.6'; @@ -41,7 +41,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {placementId: 'placement'} + params: { placementId: 'placement' } }); expect(result).to.equal(false); }); @@ -49,7 +49,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: '', placementId: 'placement'} + params: { clientToken: '', placementId: 'placement' } }); expect(result).to.equal(false); }); @@ -57,7 +57,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: 'clientToken'} + params: { clientToken: 'clientToken' } }); expect(result).to.equal(false); }); @@ -65,7 +65,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: 'clientToken', placementId: ''} + params: { clientToken: 'clientToken', placementId: '' } }); expect(result).to.equal(false); }); @@ -77,7 +77,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: 'clientToken', placementId} + params: { clientToken: 'clientToken', placementId } }); expect(result).to.equal(false); }); @@ -91,7 +91,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: 'clientToken', placementId: id} + params: { clientToken: 'clientToken', placementId: id } }); expect(result).to.equal(false); }); @@ -100,7 +100,7 @@ describe('FeedAdAdapter', function () { const result = spec.isBidRequestValid({ bidder: 'feedad', sizes: [], - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }); expect(result).to.equal(true); }); @@ -126,7 +126,7 @@ describe('FeedAdAdapter', function () { sizes: [[300, 250], [300, 600]], } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; @@ -139,7 +139,7 @@ describe('FeedAdAdapter', function () { context: 'instream' } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; @@ -152,7 +152,7 @@ describe('FeedAdAdapter', function () { context: 'outstream' } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids).to.be.lengthOf(1); @@ -166,7 +166,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids).to.be.lengthOf(1); @@ -180,7 +180,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id', another: 'parameter', more: 'parameters'} + params: { clientToken: 'clientToken', placementId: 'placement-id', another: 'parameter', more: 'parameters' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids).to.be.lengthOf(1); @@ -195,7 +195,7 @@ describe('FeedAdAdapter', function () { video: undefined, native: undefined }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result).to.be.empty; @@ -208,7 +208,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.method).to.equal('POST'); @@ -221,7 +221,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.url).to.equal('https://api.feedad.com/1/prebid/web/bids'); @@ -234,7 +234,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.options).to.deep.equal({ @@ -249,7 +249,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid, bid, bid], bidderRequest); expect(result.data).to.deep.include(bidderRequest); @@ -262,7 +262,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid, bid, bid]); expect(result).to.be.empty; @@ -275,7 +275,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.data.gdprApplies).to.be.undefined; @@ -289,7 +289,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const request = Object.assign({}, bidderRequest, { gdprConsent: { @@ -309,7 +309,7 @@ describe('FeedAdAdapter', function () { sizes: [[320, 250]] } }, - params: {clientToken: 'clientToken', placementId: 'placement-id'} + params: { clientToken: 'clientToken', placementId: 'placement-id' } }; const result = spec.buildRequests([bid], bidderRequest); expect(result.data.bids[0].params.prebid_adapter_version).to.equal(EXPECTED_ADAPTER_VERSION); @@ -322,7 +322,7 @@ describe('FeedAdAdapter', function () { const body = [{ ad: 'bar', }]; - const result = spec.interpretResponse({body: JSON.stringify(body)}); + const result = spec.interpretResponse({ body: JSON.stringify(body) }); expect(result).to.deep.equal(body); }); @@ -330,7 +330,7 @@ describe('FeedAdAdapter', function () { const body = [{ ad: 'bar', }]; - const result = spec.interpretResponse({body}); + const result = spec.interpretResponse({ body }); expect(result).to.deep.equal(body); }); @@ -347,7 +347,7 @@ describe('FeedAdAdapter', function () { ad: 'ad html', }; const body = [bid1, bid2, bid3]; - const result = spec.interpretResponse({body: JSON.stringify(body)}); + const result = spec.interpretResponse({ body: JSON.stringify(body) }); expect(result).to.deep.equal([bid1, bid3]); }); @@ -357,22 +357,22 @@ describe('FeedAdAdapter', function () { ad: 'ad html', cpm: 100 }; - const result = spec.interpretResponse({body: JSON.stringify([bid])}); + const result = spec.interpretResponse({ body: JSON.stringify([bid]) }); expect(result[0]).not.to.haveOwnProperty('ext'); }); it('should return an empty array if the response is not an array', function () { const bid = {}; - const result = spec.interpretResponse({body: JSON.stringify(bid)}); + const result = spec.interpretResponse({ body: JSON.stringify(bid) }); expect(result).to.deep.equal([]); }); }); describe('getUserSyncs', function () { - const pixelSync1 = {type: 'image', url: 'the pixel url 1'}; - const pixelSync2 = {type: 'image', url: 'the pixel url 2'}; - const iFrameSync1 = {type: 'iframe', url: 'the iFrame url 1'}; - const iFrameSync2 = {type: 'iframe', url: 'the iFrame url 2'}; + const pixelSync1 = { type: 'image', url: 'the pixel url 1' }; + const pixelSync2 = { type: 'image', url: 'the pixel url 2' }; + const iFrameSync1 = { type: 'iframe', url: 'the iFrame url 1' }; + const iFrameSync2 = { type: 'iframe', url: 'the iFrame url 2' }; const response1 = { body: [{ ext: { @@ -395,7 +395,7 @@ describe('FeedAdAdapter', function () { }] }; it('should pass through the syncs out of the extension fields of the server response', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [response1]) + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [response1]) expect(result).to.deep.equal([ pixelSync1, pixelSync2, @@ -404,7 +404,7 @@ describe('FeedAdAdapter', function () { }); it('should concat the syncs of all responses', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [response1, response2]); + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [response1, response2]); expect(result).to.deep.equal([ pixelSync1, pixelSync2, @@ -414,7 +414,7 @@ describe('FeedAdAdapter', function () { }); it('should concat the syncs of all bids', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [response2]); + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [response2]); expect(result).to.deep.equal([ pixelSync1, iFrameSync1, @@ -424,7 +424,7 @@ describe('FeedAdAdapter', function () { }); it('should filter out duplicates', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [response1, response1]); + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [response1, response1]); expect(result).to.deep.equal([ pixelSync1, pixelSync2, @@ -433,7 +433,7 @@ describe('FeedAdAdapter', function () { }); it('should not include iFrame syncs if the option is disabled', function () { - const result = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [response1]); + const result = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [response1]); expect(result).to.deep.equal([ pixelSync1, pixelSync2, @@ -441,36 +441,36 @@ describe('FeedAdAdapter', function () { }); it('should not include pixel syncs if the option is disabled', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [response1]); + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [response1]); expect(result).to.deep.equal([ iFrameSync1, ]); }); it('should not include any syncs if the sync options are disabled or missing', function () { - const result = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}, [response1]); + const result = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }, [response1]); expect(result).to.deep.equal([]); }); it('should handle empty responses', function () { - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, []) + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, []) expect(result).to.deep.equal([]); }); it('should not throw if the server response is weird', function () { const responses = [ - {body: null}, - {body: 'null'}, - {body: 1234}, - {body: {}}, - {body: [{}, 123]}, + { body: null }, + { body: 'null' }, + { body: 1234 }, + { body: {} }, + { body: [{}, 123] }, ]; - expect(() => spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, responses)).to.not.throw(); + expect(() => spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, responses)).to.not.throw(); }); it('should return empty array if the body extension is null', function () { - const response = {body: [{ext: null}]}; - const result = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [response]); + const response = { body: [{ ext: null }] }; + const result = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [response]); expect(result).to.deep.equal([]); }); }); @@ -621,7 +621,7 @@ describe('FeedAdAdapter', function () { expect(call.url).to.equal('https://api.feedad.com/1/prebid/web/events'); expect(JSON.parse(call.requestBody)).to.deep.equal(expectedData); expect(call.method).to.equal('POST'); - expect(call.requestHeaders).to.include({'Content-Type': 'application/json'}); + expect(call.requestHeaders).to.include({ 'Content-Type': 'application/json' }); }) }); }); diff --git a/test/spec/modules/finativeBidAdapter_spec.js b/test/spec/modules/finativeBidAdapter_spec.js index ebb3e9e7a3d..8b603870d41 100644 --- a/test/spec/modules/finativeBidAdapter_spec.js +++ b/test/spec/modules/finativeBidAdapter_spec.js @@ -1,6 +1,6 @@ // jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {spec} from 'modules/finativeBidAdapter.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/finativeBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; @@ -109,7 +109,7 @@ describe('Finative adapter', function () { adm: { native: { assets: [ - {id: 0, title: {text: 'this is a title'}} + { id: 0, title: { text: 'this is a title' } } ], imptrackers: ['https://domain.for/imp/tracker?price=${AUCTION_PRICE}'], link: { @@ -125,11 +125,13 @@ describe('Finative adapter', function () { ] } }; - const badResponse = { body: { - cur: 'EUR', - id: '4b516b80-886e-4ec0-82ae-9209e6d625fb', - seatbid: [] - }}; + const badResponse = { + body: { + cur: 'EUR', + id: '4b516b80-886e-4ec0-82ae-9209e6d625fb', + seatbid: [] + } + }; const bidRequest = { data: {}, diff --git a/test/spec/modules/fintezaAnalyticsAdapter_spec.js b/test/spec/modules/fintezaAnalyticsAdapter_spec.js index ed9d7b1639b..8b55532a357 100644 --- a/test/spec/modules/fintezaAnalyticsAdapter_spec.js +++ b/test/spec/modules/fintezaAnalyticsAdapter_spec.js @@ -192,7 +192,7 @@ describe('finteza analytics adapter', function () { expect(url.search.value).to.equal(String(cpm)); expect(url.search.unit).to.equal('usd'); - sinon.assert.calledWith(fntzAnalyticsAdapter.track, sinon.match({eventType: EVENTS.BID_WON})) + sinon.assert.calledWith(fntzAnalyticsAdapter.track, sinon.match({ eventType: EVENTS.BID_WON })) }); }); diff --git a/test/spec/modules/flippBidAdapter_spec.js b/test/spec/modules/flippBidAdapter_spec.js index 0e17f1d2270..9f8105d6fdc 100644 --- a/test/spec/modules/flippBidAdapter_spec.js +++ b/test/spec/modules/flippBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/flippBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; +import { expect } from 'chai'; +import { spec } from 'modules/flippBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; const ENDPOINT = 'https://ads-flipp.com/flyer-locator-service/client_bidding'; describe('flippAdapter', function () { const adapter = newBidder(spec); @@ -39,7 +39,7 @@ describe('flippAdapter', function () { }, adUnitCode: '/10000/unit_code', sizes: [[300, 600]], - mediaTypes: {banner: {sizes: [[300, 600]]}}, + mediaTypes: { banner: { sizes: [[300, 600]] } }, bidId: '237f4d1a293f99', bidderRequestId: '1a857fa34c1c96', auctionId: 'a297d1aa-7900-4ce4-a0aa-caa8d46c4af7', @@ -110,7 +110,7 @@ describe('flippAdapter', function () { } }] }, - 'location': {'city': 'Oakville'}, + 'location': { 'city': 'Oakville' }, }, }; @@ -162,7 +162,7 @@ describe('flippAdapter', function () { 'decisions': { 'inline': [] }, - 'location': {'city': 'Oakville'}, + 'location': { 'city': 'Oakville' }, }, }; diff --git a/test/spec/modules/floxisBidAdapter_spec.js b/test/spec/modules/floxisBidAdapter_spec.js new file mode 100644 index 00000000000..9cc8fe96c46 --- /dev/null +++ b/test/spec/modules/floxisBidAdapter_spec.js @@ -0,0 +1,501 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { spec } from 'modules/floxisBidAdapter.js'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes.js'; +import * as utils from 'src/utils.js'; + +describe('floxisBidAdapter', function () { + const DEFAULT_PARAMS = { seat: 'Gmtb', region: 'us-e', partner: 'floxis' }; + + const validBannerBid = { + bidId: 'bid-1', + bidder: 'floxis', + adUnitCode: 'adunit-banner', + mediaTypes: { banner: { sizes: [[300, 250], [728, 90]] } }, + params: { ...DEFAULT_PARAMS } + }; + + const validVideoBid = { + bidId: 'bid-2', + bidder: 'floxis', + adUnitCode: 'adunit-video', + mediaTypes: { + video: { + playerSize: [[640, 480]], + mimes: ['video/mp4'], + protocols: [2, 3], + context: 'instream' + } + }, + params: { ...DEFAULT_PARAMS } + }; + + const validNativeBid = { + bidId: 'bid-3', + bidder: 'floxis', + adUnitCode: 'adunit-native', + mediaTypes: { + native: { + image: { required: true, sizes: [150, 50] }, + title: { required: true, len: 80 } + } + }, + params: { ...DEFAULT_PARAMS } + }; + + describe('isBidRequestValid', function () { + it('should return true for valid banner bid', function () { + expect(spec.isBidRequestValid(validBannerBid)).to.be.true; + }); + + it('should return true for valid video bid', function () { + expect(spec.isBidRequestValid(validVideoBid)).to.be.true; + }); + + it('should return true for valid native bid', function () { + expect(spec.isBidRequestValid(validNativeBid)).to.be.true; + }); + + it('should return false when seat is missing', function () { + const bid = { ...validBannerBid, params: { region: 'us-e' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when seat is empty string', function () { + const bid = { ...validBannerBid, params: { seat: '', region: 'us-e' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return true when region is missing (default region applies)', function () { + const bid = { ...validBannerBid, params: { seat: 'Gmtb' } }; + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + + it('should return false when region is empty string', function () { + const bid = { ...validBannerBid, params: { seat: 'Gmtb', region: '' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return true when partner is missing (default partner applies)', function () { + const bid = { ...validBannerBid, params: { seat: 'Gmtb', region: 'us-e' } }; + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + + it('should return false when partner is empty string', function () { + const bid = { ...validBannerBid, params: { seat: 'Gmtb', region: 'us-e', partner: '' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when params is missing', function () { + const bid = { bidId: 'x', mediaTypes: { banner: { sizes: [[300, 250]] } } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when seat is not a string', function () { + const bid = { ...validBannerBid, params: { seat: 123, region: 'us-e', partner: 'floxis' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when region is not in whitelist', function () { + const bid = { ...validBannerBid, params: { ...DEFAULT_PARAMS, region: 'eu-w' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when partner is not in whitelist', function () { + const bid = { ...validBannerBid, params: { ...DEFAULT_PARAMS, partner: 'mypartner' } }; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return true with default partner', function () { + const bid = { ...validBannerBid, params: { ...DEFAULT_PARAMS, partner: 'floxis' } }; + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + }); + + describe('supportedMediaTypes', function () { + it('should include banner, video, and native', function () { + expect(spec.supportedMediaTypes).to.deep.equal([BANNER, VIDEO, NATIVE]); + }); + }); + + describe('buildRequests', function () { + const bidderRequest = { + bidderCode: 'floxis', + auctionId: 'auction-123', + timeout: 3000 + }; + + it('should return an array with one POST request', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + expect(requests).to.be.an('array').with.lengthOf(1); + expect(requests[0].method).to.equal('POST'); + }); + + it('should build URL without partner prefix when partner is floxis', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + expect(requests[0].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Gmtb'); + }); + + it('should return no requests for non-whitelisted partner', function () { + const bidWithPartner = { + ...validBannerBid, + params: { ...DEFAULT_PARAMS, partner: 'mypartner' } + }; + const requests = spec.buildRequests([bidWithPartner], bidderRequest); + expect(requests).to.be.an('array').that.is.empty; + }); + + it('should default region to us-e when missing', function () { + const bidWithoutRegion = { + ...validBannerBid, + params: { seat: 'Gmtb', partner: 'floxis' } + }; + const requests = spec.buildRequests([bidWithoutRegion], bidderRequest); + expect(requests[0].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Gmtb'); + }); + + it('should default partner to floxis when missing', function () { + const bidWithoutPartner = { + ...validBannerBid, + params: { seat: 'Gmtb', region: 'us-e' } + }; + const requests = spec.buildRequests([bidWithoutPartner], bidderRequest); + expect(requests[0].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Gmtb'); + }); + + it('should return empty array for empty bid requests', function () { + const requests = spec.buildRequests([], bidderRequest); + expect(requests).to.be.an('array').that.is.empty; + }); + + it('should produce valid ORTB request payload', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + const data = requests[0].data; + expect(data).to.be.an('object'); + expect(data.imp).to.be.an('array').with.lengthOf(1); + expect(data.at).to.equal(1); + }); + + it('should set ext with adapter info', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + const data = requests[0].data; + expect(data.ext.prebid.adapter).to.equal('floxis'); + expect(data.ext.prebid.adapterVersion).to.be.undefined; + expect(data.ext.prebid.version).to.equal('$prebid.version$'); + }); + + it('should build banner imp correctly', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + const imp = requests[0].data.imp[0]; + expect(imp).to.have.property('banner'); + expect(imp.banner.format).to.be.an('array'); + expect(imp.secure).to.equal(1); + }); + + if (FEATURES.VIDEO) { + it('should build video imp correctly', function () { + const requests = spec.buildRequests([validVideoBid], bidderRequest); + const imp = requests[0].data.imp[0]; + expect(imp).to.have.property('video'); + expect(imp.video.mimes).to.deep.equal(['video/mp4']); + expect(imp.video.protocols).to.deep.equal([2, 3]); + }); + } + + it('should handle multiple bids in single request', function () { + const requests = spec.buildRequests([validBannerBid, validVideoBid], bidderRequest); + expect(requests).to.have.lengthOf(1); + expect(requests[0].data.imp).to.have.lengthOf(2); + }); + + it('should split requests by seat when using allowed defaults', function () { + const mixedBid = { + ...validVideoBid, + params: { + seat: 'Seat2', + region: 'us-e', + partner: 'floxis' + } + }; + + const requests = spec.buildRequests([validBannerBid, mixedBid], bidderRequest); + expect(requests).to.have.lengthOf(2); + expect(requests[0].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Gmtb'); + expect(requests[1].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Seat2'); + expect(requests[0].data.imp).to.have.lengthOf(1); + expect(requests[1].data.imp).to.have.lengthOf(1); + }); + + it('should ignore non-whitelisted bids in mixed request arrays', function () { + const invalidBid = { + ...validVideoBid, + params: { + seat: 'Seat2', + region: 'eu-w', + partner: 'mypartner' + } + }; + + const requests = spec.buildRequests([validBannerBid, invalidBid], bidderRequest); + expect(requests).to.have.lengthOf(1); + expect(requests[0].url).to.equal('https://us-e.floxis.tech/pbjs?seat=Gmtb'); + expect(requests[0].data.imp).to.have.lengthOf(1); + }); + + it('should set withCredentials option', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + expect(requests[0].options.withCredentials).to.be.true; + }); + + describe('Floors Module support', function () { + it('should set bidfloor from getFloor', function () { + const bidWithFloor = { + ...validBannerBid, + getFloor: function () { + return { floor: 2.5, currency: 'USD' }; + } + }; + const requests = spec.buildRequests([bidWithFloor], bidderRequest); + const imp = requests[0].data.imp[0]; + expect(imp.bidfloor).to.equal(2.5); + expect(imp.bidfloorcur).to.equal('USD'); + }); + + it('should not set bidfloor when getFloor is not present', function () { + const requests = spec.buildRequests([validBannerBid], bidderRequest); + const imp = requests[0].data.imp[0]; + expect(imp.bidfloor).to.be.undefined; + }); + + it('should handle getFloor throwing an error gracefully', function () { + const bidBrokenFloor = { + ...validBannerBid, + getFloor: function () { + throw new Error('floor error'); + } + }; + const requests = spec.buildRequests([bidBrokenFloor], bidderRequest); + const imp = requests[0].data.imp[0]; + expect(imp.bidfloor).to.be.undefined; + }); + }); + + describe('ortb2 passthrough', function () { + it('should merge ortb2 data into the ORTB request', function () { + const ortb2BidderRequest = { + ...bidderRequest, + ortb2: { + regs: { ext: { gdpr: 1 } }, + user: { ext: { consent: 'consent-string-123' } } + } + }; + const requests = spec.buildRequests([validBannerBid], ortb2BidderRequest); + const data = requests[0].data; + expect(data.regs.ext.gdpr).to.equal(1); + expect(data.user.ext.consent).to.equal('consent-string-123'); + }); + + it('should merge ortb2 USP data into the ORTB request', function () { + const uspBidderRequest = { + ...bidderRequest, + ortb2: { + regs: { ext: { us_privacy: '1YNN' } } + } + }; + const requests = spec.buildRequests([validBannerBid], uspBidderRequest); + const data = requests[0].data; + expect(data.regs.ext.us_privacy).to.equal('1YNN'); + }); + }); + }); + + describe('interpretResponse', function () { + function buildRequest() { + return spec.buildRequests([validBannerBid], { + bidderCode: 'floxis', + auctionId: 'auction-123' + })[0]; + } + + it('should parse valid banner ORTB response', function () { + const request = buildRequest(); + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: validBannerBid.bidId, + price: 1.23, + w: 300, + h: 250, + crid: 'creative-1', + adm: '
ad
', + mtype: 1 + }] + }] + } + }; + const bids = spec.interpretResponse(serverResponse, request); + expect(bids).to.be.an('array').with.lengthOf(1); + expect(bids[0].cpm).to.equal(1.23); + expect(bids[0].width).to.equal(300); + expect(bids[0].height).to.equal(250); + expect(bids[0].creativeId).to.equal('creative-1'); + expect(bids[0].ad).to.equal('
ad
'); + expect(bids[0].requestId).to.equal(validBannerBid.bidId); + expect(bids[0].netRevenue).to.equal(true); + expect(bids[0].currency).to.equal('USD'); + }); + + if (FEATURES.VIDEO) { + it('should parse valid video ORTB response', function () { + const videoRequest = spec.buildRequests([validVideoBid], { + bidderCode: 'floxis', + auctionId: 'auction-456' + })[0]; + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: validVideoBid.bidId, + price: 5.00, + w: 640, + h: 480, + crid: 'video-creative-1', + adm: '', + mtype: 2 + }] + }] + } + }; + const bids = spec.interpretResponse(serverResponse, videoRequest); + expect(bids).to.be.an('array').with.lengthOf(1); + expect(bids[0].cpm).to.equal(5.00); + expect(bids[0].vastXml).to.equal(''); + expect(bids[0].mediaType).to.equal(VIDEO); + }); + } + + it('should return empty array for empty response', function () { + const request = buildRequest(); + const bids = spec.interpretResponse({ body: {} }, request); + expect(bids).to.be.an('array').that.is.empty; + }); + + it('should return empty array for null response body', function () { + const request = buildRequest(); + const bids = spec.interpretResponse({ body: null }, request); + expect(bids).to.be.an('array').that.is.empty; + }); + + it('should return empty array for undefined response', function () { + const request = buildRequest(); + const bids = spec.interpretResponse(undefined, request); + expect(bids).to.be.an('array').that.is.empty; + }); + + it('should return empty array for undefined request', function () { + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: validBannerBid.bidId, + price: 1.23, + w: 300, + h: 250, + crid: 'creative-1', + adm: '
ad
', + mtype: 1 + }] + }] + } + }; + const bids = spec.interpretResponse(serverResponse, undefined); + expect(bids).to.be.an('array').that.is.empty; + }); + + it('should handle multiple bids in seatbid', function () { + const bids2 = [ + { ...validBannerBid, bidId: 'bid-a' }, + { ...validBannerBid, bidId: 'bid-b', adUnitCode: 'adunit-2' } + ]; + const request = spec.buildRequests(bids2, { bidderCode: 'floxis', auctionId: 'a1' })[0]; + const serverResponse = { + body: { + seatbid: [{ + bid: [ + { impid: 'bid-a', price: 1.0, w: 300, h: 250, crid: 'c1', adm: '
1
', mtype: 1 }, + { impid: 'bid-b', price: 2.0, w: 300, h: 250, crid: 'c2', adm: '
2
', mtype: 1 } + ] + }] + } + }; + const result = spec.interpretResponse(serverResponse, request); + expect(result).to.have.lengthOf(2); + expect(result[0].cpm).to.equal(1.0); + expect(result[1].cpm).to.equal(2.0); + }); + + it('should set advertiserDomains from adomain', function () { + const request = buildRequest(); + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: validBannerBid.bidId, + price: 1.0, + w: 300, + h: 250, + crid: 'c1', + adm: '
ad
', + adomain: ['adv.com'], + mtype: 1 + }] + }] + } + }; + const bids = spec.interpretResponse(serverResponse, request); + expect(bids[0].meta.advertiserDomains).to.deep.equal(['adv.com']); + }); + }); + + describe('getUserSyncs', function () { + it('should return empty array', function () { + expect(spec.getUserSyncs()).to.be.an('array').that.is.empty; + }); + }); + + describe('onBidWon', function () { + let triggerPixelStub; + + beforeEach(function () { + triggerPixelStub = sinon.stub(utils, 'triggerPixel'); + }); + + afterEach(function () { + triggerPixelStub.restore(); + }); + + it('should fire burl pixel', function () { + spec.onBidWon({ burl: 'https://example.com/burl' }); + expect(triggerPixelStub.calledWith('https://example.com/burl')).to.be.true; + }); + + it('should fire nurl pixel', function () { + spec.onBidWon({ nurl: 'https://example.com/nurl' }); + expect(triggerPixelStub.calledWith('https://example.com/nurl')).to.be.true; + }); + + it('should fire both burl and nurl pixels', function () { + spec.onBidWon({ + burl: 'https://example.com/burl', + nurl: 'https://example.com/nurl' + }); + expect(triggerPixelStub.callCount).to.equal(2); + }); + + it('should not fire pixels when no urls present', function () { + spec.onBidWon({}); + expect(triggerPixelStub.called).to.be.false; + }); + }); +}); diff --git a/test/spec/modules/fluctBidAdapter_spec.js b/test/spec/modules/fluctBidAdapter_spec.js index cdc99694d52..b59b1e99e98 100644 --- a/test/spec/modules/fluctBidAdapter_spec.js +++ b/test/spec/modules/fluctBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/fluctBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {config} from 'src/config'; +import { expect } from 'chai'; +import { spec } from 'modules/fluctBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; +import { config } from 'src/config'; describe('fluctAdapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/fpdModule_spec.js b/test/spec/modules/fpdModule_spec.js index 4536b304f9d..7c9c89e05ab 100644 --- a/test/spec/modules/fpdModule_spec.js +++ b/test/spec/modules/fpdModule_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {registerSubmodules, reset, startAuctionHook} from 'modules/fpdModule/index.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { registerSubmodules, reset, startAuctionHook } from 'modules/fpdModule/index.js'; describe('the first party data module', function () { afterEach(function () { @@ -12,8 +12,8 @@ describe('the first party data module', function () { describe('startAuctionHook', () => { const mockFpd = { - global: {key: 'value'}, - bidder: {A: {bkey: 'bvalue'}} + global: { key: 'value' }, + bidder: { A: { bkey: 'bvalue' } } } beforeEach(() => { reset(); @@ -26,7 +26,7 @@ describe('the first party data module', function () { return mockFpd; } }); - const req = {ortb2Fragments: {}}; + const req = { ortb2Fragments: {} }; return new Promise((resolve) => startAuctionHook(resolve, req)) .then(() => { expect(req.ortb2Fragments).to.eql(mockFpd); @@ -40,7 +40,7 @@ describe('the first party data module', function () { return Promise.resolve(mockFpd); } }); - const req = {ortb2Fragments: {}}; + const req = { ortb2Fragments: {} }; return new Promise((resolve) => { startAuctionHook(resolve, req); }).then(() => { diff --git a/test/spec/modules/freeWheelAdserverVideo_spec.js b/test/spec/modules/freeWheelAdserverVideo_spec.js index 3da5b411e37..0c65bbefc7e 100644 --- a/test/spec/modules/freeWheelAdserverVideo_spec.js +++ b/test/spec/modules/freeWheelAdserverVideo_spec.js @@ -185,7 +185,7 @@ describe('freeWheel adserver module', function() { server.requests[0].respond( 200, { 'Content-Type': 'text/plain' }, - JSON.stringify({'responses': getBidsReceived().slice(0, 4)}) + JSON.stringify({ 'responses': getBidsReceived().slice(0, 4) }) ); expect(targeting['preroll_1'].length).to.equal(3); @@ -222,13 +222,13 @@ describe('freeWheel adserver module', function() { server.requests[0].respond( 200, { 'Content-Type': 'text/plain' }, - JSON.stringify({'responses': bidsReceived.slice(1)}) + JSON.stringify({ 'responses': bidsReceived.slice(1) }) ); expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['preroll_1']).to.deep.include({'hb_pb_cat_dur': 'tier6_395_15s'}); - expect(targeting['preroll_1']).to.deep.include({'hb_pb_cat_dur': 'tier7_395_15s'}); - expect(targeting['preroll_1']).to.deep.include({'hb_cache_id': '123'}); + expect(targeting['preroll_1']).to.deep.include({ 'hb_pb_cat_dur': 'tier6_395_15s' }); + expect(targeting['preroll_1']).to.deep.include({ 'hb_pb_cat_dur': 'tier7_395_15s' }); + expect(targeting['preroll_1']).to.deep.include({ 'hb_cache_id': '123' }); }); it('should apply minDealTier to bids if configured', function() { @@ -272,14 +272,14 @@ describe('freeWheel adserver module', function() { server.requests[0].respond( 200, { 'Content-Type': 'text/plain' }, - JSON.stringify({'responses': [tier7Bid, bid]}) + JSON.stringify({ 'responses': [tier7Bid, bid] }) ); expect(targeting['preroll_1'].length).to.equal(3); - expect(targeting['preroll_1']).to.deep.include({'hb_pb_cat_dur': 'tier7_395_15s'}); - expect(targeting['preroll_1']).to.deep.include({'hb_pb_cat_dur': '15.00_395_90s'}); - expect(targeting['preroll_1']).to.not.include({'hb_pb_cat_dur': 'tier2_395_15s'}); - expect(targeting['preroll_1']).to.deep.include({'hb_cache_id': '123'}); + expect(targeting['preroll_1']).to.deep.include({ 'hb_pb_cat_dur': 'tier7_395_15s' }); + expect(targeting['preroll_1']).to.deep.include({ 'hb_pb_cat_dur': '15.00_395_90s' }); + expect(targeting['preroll_1']).to.not.include({ 'hb_pb_cat_dur': 'tier2_395_15s' }); + expect(targeting['preroll_1']).to.deep.include({ 'hb_cache_id': '123' }); }) }); diff --git a/test/spec/modules/freepassBidAdapter_spec.js b/test/spec/modules/freepassBidAdapter_spec.js index b36639f573b..2a66348f5a4 100644 --- a/test/spec/modules/freepassBidAdapter_spec.js +++ b/test/spec/modules/freepassBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/freepassBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec } from 'modules/freepassBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('FreePass adapter', function () { const adapter = newBidder(spec); diff --git a/test/spec/modules/ftrackIdSystem_spec.js b/test/spec/modules/ftrackIdSystem_spec.js index 5e3b31dc11b..bec1fa8489c 100644 --- a/test/spec/modules/ftrackIdSystem_spec.js +++ b/test/spec/modules/ftrackIdSystem_spec.js @@ -3,10 +3,10 @@ import * as utils from 'src/utils.js'; import { uspDataHandler } from 'src/adapterManager.js'; import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js'; import { getGlobal } from 'src/prebidGlobal.js'; -import {attachIdSystem, init, setSubmoduleRegistry} from 'modules/userId/index.js'; -import {createEidsArray} from 'modules/userId/eids.js'; -import {config} from 'src/config.js'; -import {server} from 'test/mocks/xhr.js'; +import { attachIdSystem, init, setSubmoduleRegistry } from 'modules/userId/index.js'; +import { createEidsArray } from 'modules/userId/eids.js'; +import { config } from 'src/config.js'; +import { server } from 'test/mocks/xhr.js'; import 'src/prebid.js'; const configMock = { @@ -106,26 +106,26 @@ describe('FTRACK ID System', () => { describe(`ftrackIdSubmodule.isThereConsent():`, () => { describe(`returns 'false' if:`, () => { it(`GDPR: if gdprApplies is truthy`, () => { - expect(ftrackIdSubmodule.isThereConsent({gdpr: {gdprApplies: 1}})).to.not.be.ok; - expect(ftrackIdSubmodule.isThereConsent({gdpr: {gdprApplies: true}})).to.not.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ gdpr: { gdprApplies: 1 } })).to.not.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ gdpr: { gdprApplies: true } })).to.not.be.ok; }); it(`US_PRIVACY version 1: if 'Opt Out Sale' is 'Y'`, () => { - expect(ftrackIdSubmodule.isThereConsent({usp: '1YYY'})).to.not.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ usp: '1YYY' })).to.not.be.ok; }); }); describe(`returns 'true' if`, () => { it(`GDPR: if gdprApplies is undefined, false or 0`, () => { - expect(ftrackIdSubmodule.isThereConsent({gdpr: {gdprApplies: 0}})).to.be.ok; - expect(ftrackIdSubmodule.isThereConsent({gdpr: {gdprApplies: false}})).to.be.ok; - expect(ftrackIdSubmodule.isThereConsent({gdpr: {gdprApplies: null}})).to.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ gdpr: { gdprApplies: 0 } })).to.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ gdpr: { gdprApplies: false } })).to.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ gdpr: { gdprApplies: null } })).to.be.ok; expect(ftrackIdSubmodule.isThereConsent({})).to.be.ok; }); it(`US_PRIVACY version 1: if 'Opt Out Sale' is not 'Y' ('N','-')`, () => { - expect(ftrackIdSubmodule.isThereConsent({usp: '1NNN'})).to.be.ok; - expect(ftrackIdSubmodule.isThereConsent({usp: '1---'})).to.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ usp: '1NNN' })).to.be.ok; + expect(ftrackIdSubmodule.isThereConsent({ usp: '1---' })).to.be.ok; }); }); }); @@ -147,7 +147,7 @@ describe('FTRACK ID System', () => { expect(loadExternalScriptStub.args).to.deep.equal([]); loadExternalScriptStub.resetHistory(); - ftrackIdSubmodule.extendId(configMock, null, {cache: {id: ''}}); + ftrackIdSubmodule.extendId(configMock, null, { cache: { id: '' } }); expect(loadExternalScriptStub.called).to.not.be.ok; expect(loadExternalScriptStub.args).to.deep.equal([]); @@ -323,13 +323,13 @@ describe('FTRACK ID System', () => { describe(`extendId() method`, () => { it(`should not be making requests to retrieve a new ID, it should just be adding additional data to the id object`, () => { - ftrackIdSubmodule.extendId(configMock, null, {cache: {id: ''}}); + ftrackIdSubmodule.extendId(configMock, null, { cache: { id: '' } }); expect(server.requests).to.have.length(0); }); it(`should return cacheIdObj`, () => { - expect(ftrackIdSubmodule.extendId(configMock, null, {cache: {id: ''}})).to.deep.equal({cache: {id: ''}}); + expect(ftrackIdSubmodule.extendId(configMock, null, { cache: { id: '' } })).to.deep.equal({ cache: { id: '' } }); }); }); diff --git a/test/spec/modules/gamAdServerVideo_spec.js b/test/spec/modules/gamAdServerVideo_spec.js index a8ce01c1457..43fef33d8d3 100644 --- a/test/spec/modules/gamAdServerVideo_spec.js +++ b/test/spec/modules/gamAdServerVideo_spec.js @@ -1,22 +1,23 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import parse from 'url-parse'; -import {buildGamVideoUrl as buildDfpVideoUrl, dep} from 'modules/gamAdServerVideo.js'; +import { buildGamVideoUrl as buildDfpVideoUrl, dep } from 'modules/gamAdServerVideo.js'; import AD_UNIT from 'test/fixtures/video/adUnit.json'; import * as utils from 'src/utils.js'; -import {deepClone} from 'src/utils.js'; -import {config} from 'src/config.js'; -import {targeting} from 'src/targeting.js'; -import {auctionManager} from 'src/auctionManager.js'; -import {gdprDataHandler} from 'src/adapterManager.js'; +import { deepClone } from 'src/utils.js'; +import { config } from 'src/config.js'; +import { targeting } from 'src/targeting.js'; +import { auctionManager } from 'src/auctionManager.js'; +import { gdprDataHandler } from 'src/adapterManager.js'; import * as adServer from 'src/adserver.js'; -import {hook} from '../../../src/hook.js'; -import {stubAuctionIndex} from '../../helpers/indexStub.js'; -import {AuctionIndex} from '../../../src/auctionIndex.js'; +import { hook } from '../../../src/hook.js'; +import { stubAuctionIndex } from '../../helpers/indexStub.js'; +import { AuctionIndex } from '../../../src/auctionIndex.js'; import { getVastXml } from '../../../modules/gamAdServerVideo.js'; import { server } from '../../mocks/xhr.js'; import { generateUUID } from '../../../src/utils.js'; +import { uspDataHandler, gppDataHandler } from '../../../src/consentHandler.js'; describe('The DFP video support module', function () { before(() => { @@ -70,13 +71,13 @@ describe('The DFP video support module', function () { }).forEach(([t, options]) => { describe(`when using ${t}`, () => { it('should use page location as default for description_url', () => { - sandbox.stub(dep, 'ri').callsFake(() => ({page: 'example.com'})); + sandbox.stub(dep, 'ri').callsFake(() => ({ page: 'example.com' })); const prm = getQueryParams(options); expect(prm.description_url).to.eql('example.com'); }); it('should use a URI encoded page location as default for description_url', () => { - sandbox.stub(dep, 'ri').callsFake(() => ({page: 'https://example.com?iu=/99999999/news&cust_params=current_hour%3D12%26newscat%3Dtravel&pbjs_debug=true'})); + sandbox.stub(dep, 'ri').callsFake(() => ({ page: 'https://example.com?iu=/99999999/news&cust_params=current_hour%3D12%26newscat%3Dtravel&pbjs_debug=true' })); const prm = getQueryParams(options); expect(prm.description_url).to.eql('https%3A%2F%2Fexample.com%3Fiu%3D%2F99999999%2Fnews%26cust_params%3Dcurrent_hour%253D12%2526newscat%253Dtravel%26pbjs_debug%3Dtrue'); }); @@ -192,8 +193,8 @@ describe('The DFP video support module', function () { }); Object.entries({ - 'params': {params: {'iu': 'mock/unit'}}, - 'url': {url: 'https://video.adserver.mock/', params: {'iu': 'mock/unit'}} + 'params': { params: { 'iu': 'mock/unit' } }, + 'url': { url: 'https://video.adserver.mock/', params: { 'iu': 'mock/unit' } } }).forEach(([t, opts]) => { describe(`when using ${t}`, () => { it('should be included if available', () => { @@ -319,7 +320,7 @@ describe('The DFP video support module', function () { ] }).forEach(([param, cases]) => { describe(param, () => { - cases.forEach(({video, expected}) => { + cases.forEach(({ video, expected }) => { describe(`when mediaTypes.video has ${JSON.stringify(video)}`, () => { it(`fills in ${param} = ${expected}`, () => { Object.assign(adUnit.mediaTypes.video, video); @@ -384,8 +385,8 @@ describe('The DFP video support module', function () { data: [ { segment: [ - {id: '1'}, - {id: '2'} + { id: '1' }, + { id: '2' } ] }, ] @@ -398,7 +399,7 @@ describe('The DFP video support module', function () { segtax: 1, }, segment: [ - {id: '3'} + { id: '3' } ] } ] @@ -413,8 +414,8 @@ describe('The DFP video support module', function () { segtax: 4, }, segment: [ - {id: '4-1'}, - {id: '4-2'} + { id: '4-1' }, + { id: '4-2' } ] }, { @@ -422,8 +423,8 @@ describe('The DFP video support module', function () { segtax: 4, }, segment: [ - {id: '4-2'}, - {id: '4-3'} + { id: '4-2' }, + { id: '4-3' } ] }, { @@ -431,8 +432,8 @@ describe('The DFP video support module', function () { segtax: 6, }, segment: [ - {id: '6-1'}, - {id: '6-2'} + { id: '6-1' }, + { id: '6-2' } ] }, { @@ -440,8 +441,8 @@ describe('The DFP video support module', function () { segtax: 6, }, segment: [ - {id: '6-2'}, - {id: '6-3'} + { id: '6-2' }, + { id: '6-3' } ] }, ] @@ -498,7 +499,7 @@ describe('The DFP video support module', function () { before(function () { targetingStub = sinon.stub(targeting, 'getAllTargeting'); - targetingStub.returns({'video1': allTargetingData}); + targetingStub.returns({ 'video1': allTargetingData }); config.setConfig({ enableSendAllBids: true @@ -733,7 +734,7 @@ describe('The DFP video support module', function () { }); it('should substitue vast ad tag uri in gam wrapper with blob content in data uri format', (done) => { - config.setConfig({cache: { useLocal: true }}); + config.setConfig({ cache: { useLocal: true } }); const url = 'https://pubads.g.doubleclick.net/gampad/ads' const blobContent = '` + `` + @@ -870,4 +871,332 @@ describe('The DFP video support module', function () { .finally(config.resetConfig); server.respond(); }); + + describe('Retrieve US Privacy string from GPP when using the IMA player', () => { + beforeEach(() => { + config.setConfig({ cache: { useLocal: true } }); + // Install a fake IMA object, because the us_privacy is only set when IMA is available + window.google = { + ima: { + VERSION: '2.3.37' + } + } + }) + afterEach(() => { + config.resetConfig(); + }) + + async function obtainUsPrivacyInVastXmlRequest() { + const url = 'https://pubads.g.doubleclick.net/gampad/ads' + const bidCacheUrl = 'https://prebid-test-cache-server.org/cache?uuid=4536229c-eddb-45b3-a919-89d889e925aa'; + const gamWrapper = ( + `` + + `` + + `` + + `prebid.org wrapper` + + `` + + `` + + `` + + `` + ); + server.respondWith(gamWrapper); + + const result = getVastXml({url, adUnit: {}, bid: {}, params: {iu: '/19968336/prebid_cache_video_adunit'}}, []).then(() => { + const request = server.requests[0]; + const url = new URL(request.url); + return url.searchParams.get('us_privacy'); + }); + server.respond(); + + return result; + } + + function obtainUsPrivacyInGamVideoUrl() { + const url = 'https://pubads.g.doubleclick.net/gampad/ads' + return new URLSearchParams(buildDfpVideoUrl({url, adUnit: {}, bid: {}, params: {iu: '/19968336/prebid_cache_video_adunit'}})).get('us_privacy'); + } + + function mockGpp(gpp) { + sandbox.stub(gppDataHandler, 'getConsentData').returns(gpp) + } + + function wrapParsedSectionsIntoGPPData(parsedSections) { + return { + gppData: { + parsedSections: parsedSections + } + } + } + + it('should use usp when available, even when gpp is available', async () => { + const usPrivacy = '1YYY'; + sandbox.stub(uspDataHandler, 'getConsentData').returns(usPrivacy); + mockGpp(wrapParsedSectionsIntoGPPData({ + "uspv1": { + "Version": 1, + "Notice": "Y", + "OptOutSale": "N", + "LspaCovered": "Y" + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.equal(usPrivacy); + + // In this case, the IMA player will add the us_privacy string + // It is not included in the URL returned by Prebid + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.be.null; + }) + + it('no us_privacy when neither usp nor gpp is present', async () => { + const usPrivacyFromRequqest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequqest).to.be.null; + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.be.null; + }) + + it('can retrieve from usp section in gpp', async () => { + mockGpp(wrapParsedSectionsIntoGPPData({ + "uspv1": { + "Version": 1, + "Notice": "Y", + "OptOutSale": "N", + "LspaCovered": "Y" + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.equal('1YNY'); + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.equal('1YNY'); + }) + it('can retrieve from usnat section in gpp', async () => { + mockGpp(wrapParsedSectionsIntoGPPData({ + "usnat": { + "Version": 1, + "SharingNotice": 2, + "SaleOptOutNotice": 1, + "SharingOptOutNotice": 0, + "TargetedAdvertisingOptOutNotice": 2, + "SensitiveDataProcessingOptOutNotice": 1, + "SensitiveDataLimitUseNotice": 1, + "SaleOptOut": 1, + "SharingOptOut": 2, + "TargetedAdvertisingOptOut": 2, + "SensitiveDataProcessing": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "KnownChildSensitiveDataConsents": [ + 0, + 0, + 0 + ], + "PersonalDataConsents": 0, + "MspaCoveredTransaction": 1, + "MspaOptOutOptionMode": 0, + "MspaServiceProviderMode": 0, + "GpcSegmentType": 1, + "Gpc": false + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.equal('1YYY'); + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.equal('1YYY'); + }) + it('can retrieve from usnat section in gpp when usnat is an array', async() => { + mockGpp(wrapParsedSectionsIntoGPPData({ + "usnat": [ + { + "Version": 1, + "SharingNotice": 2, + "SaleOptOutNotice": 1, + "SharingOptOutNotice": 1, + "TargetedAdvertisingOptOutNotice": 1, + "SensitiveDataProcessingOptOutNotice": 1, + "SensitiveDataLimitUseNotice": 0, + "SaleOptOut": 2, + "SharingOptOut": 2, + "TargetedAdvertisingOptOut": 2, + "PersonalDataConsents": 0, + "MspaCoveredTransaction": 0, + "MspaOptOutOptionMode": 0, + "MspaServiceProviderMode": 0, + }, { + "GpcSegmentType": 1, + "Gpc": false + } + ] + })) + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.equal('1YNY'); + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.equal('1YNY'); + }) + it('no us_privacy when either SaleOptOutNotice or SaleOptOut is missing', async () => { + // Missing SaleOptOutNotice + mockGpp(wrapParsedSectionsIntoGPPData({ + "usnat": { + "Version": 1, + "SharingNotice": 2, + "SharingOptOutNotice": 0, + "TargetedAdvertisingOptOutNotice": 2, + "SensitiveDataProcessingOptOutNotice": 1, + "SensitiveDataLimitUseNotice": 1, + "SaleOptOut": 1, + "SharingOptOut": 2, + "TargetedAdvertisingOptOut": 2, + "SensitiveDataProcessing": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "KnownChildSensitiveDataConsents": [ + 0, + 0, + 0 + ], + "PersonalDataConsents": 0, + "MspaCoveredTransaction": 1, + "MspaOptOutOptionMode": 0, + "MspaServiceProviderMode": 0, + "GpcSegmentType": 1, + "Gpc": false + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.be.null; + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.be.null; + }) + it('no us_privacy when either SaleOptOutNotice or SaleOptOut is null', async () => { + // null SaleOptOut + mockGpp(wrapParsedSectionsIntoGPPData({ + "usnat": { + "Version": 1, + "SharingNotice": 2, + "SaleOptOutNotice": 1, + "SharingOptOutNotice": 0, + "TargetedAdvertisingOptOutNotice": 2, + "SensitiveDataProcessingOptOutNotice": 1, + "SensitiveDataLimitUseNotice": 1, + "SaleOptOut": null, + "SharingOptOut": 2, + "TargetedAdvertisingOptOut": 2, + "SensitiveDataProcessing": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "KnownChildSensitiveDataConsents": [ + 0, + 0, + 0 + ], + "PersonalDataConsents": 0, + "MspaCoveredTransaction": 1, + "MspaOptOutOptionMode": 0, + "MspaServiceProviderMode": 0, + "GpcSegmentType": 1, + "Gpc": false + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.be.null; + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.be.null; + }) + + it('can retrieve from usca section in gpp', async () => { + mockGpp(wrapParsedSectionsIntoGPPData({ + "usca": { + "Version": 1, + "SaleOptOutNotice": 1, + "SharingOptOutNotice": 1, + "SensitiveDataLimitUseNotice": 1, + "SaleOptOut": 2, + "SharingOptOut": 2, + "SensitiveDataProcessing": [ + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "KnownChildSensitiveDataConsents": [ + 0, + 0 + ], + "PersonalDataConsents": 0, + "MspaCoveredTransaction": 2, + "MspaOptOutOptionMode": 0, + "MspaServiceProviderMode": 0, + "GpcSegmentType": 1, + "Gpc": false + } + })); + + const usPrivacyFromRequest = await obtainUsPrivacyInVastXmlRequest(); + expect(usPrivacyFromRequest).to.equal('1YNY'); + + const usPrivacyFromUrl = obtainUsPrivacyInGamVideoUrl(); + expect(usPrivacyFromUrl).to.equal('1YNY'); + }) + }); }); diff --git a/test/spec/modules/gamAdpod_spec.js b/test/spec/modules/gamAdpod_spec.js index 31e142d11f8..bd32a23c956 100644 --- a/test/spec/modules/gamAdpod_spec.js +++ b/test/spec/modules/gamAdpod_spec.js @@ -1,11 +1,11 @@ -import {auctionManager} from '../../../src/auctionManager.js'; -import {config} from '../../../src/config.js'; -import {gdprDataHandler, uspDataHandler} from '../../../src/consentHandler.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { config } from '../../../src/config.js'; +import { gdprDataHandler, uspDataHandler } from '../../../src/consentHandler.js'; import parse from 'url-parse'; -import {buildAdpodVideoUrl} from '../../../modules/gamAdpod.js'; -import {expect} from 'chai/index.js'; +import { buildAdpodVideoUrl } from '../../../modules/gamAdpod.js'; +import { expect } from 'chai/index.js'; import * as utils from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; import * as adpod from 'modules/adpod.js'; describe('gamAdpod', function () { diff --git a/test/spec/modules/gammaBidAdapter_spec.js b/test/spec/modules/gammaBidAdapter_spec.js index bff11ded9fa..cd66741cecb 100644 --- a/test/spec/modules/gammaBidAdapter_spec.js +++ b/test/spec/modules/gammaBidAdapter_spec.js @@ -90,7 +90,7 @@ describe('gammaBidAdapter', function() { 'netRevenue': true, 'ttl': 300, 'ad': '', - 'meta': {'advertiserDomains': ['testdomain.com']} + 'meta': { 'advertiserDomains': ['testdomain.com'] } }]; const result = spec.interpretResponse(serverResponse); expect(Object.keys(result)).to.deep.equal(Object.keys(expectedResponse)); diff --git a/test/spec/modules/gamoshiBidAdapter_spec.js b/test/spec/modules/gamoshiBidAdapter_spec.js index c57000b4de1..9b9565ef7ce 100644 --- a/test/spec/modules/gamoshiBidAdapter_spec.js +++ b/test/spec/modules/gamoshiBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec, helper} from 'modules/gamoshiBidAdapter.js'; +import { expect } from 'chai'; +import { spec, helper } from 'modules/gamoshiBidAdapter.js'; import * as utils from 'src/utils.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; @@ -55,7 +55,7 @@ describe('GamoshiAdapter', () => { tid: 'a123456789', } }, - refererInfo: {referer: 'http://examplereferer.com'}, + refererInfo: { referer: 'http://examplereferer.com' }, gdprConsent: { consentString: 'some string', gdprApplies: true @@ -81,7 +81,7 @@ describe('GamoshiAdapter', () => { 'sizes': [[300, 250], [300, 600]], 'transactionId': '1d1a030790a475', 'bidId': 'request-id-12345', - refererInfo: {referer: 'http://examplereferer.com'} + refererInfo: { referer: 'http://examplereferer.com' } }; bannerRequestWithEids = { @@ -112,7 +112,7 @@ describe('GamoshiAdapter', () => { 'sizes': [[300, 250], [300, 600]], 'transactionId': '1d1a030790a475', 'bidId': 'request-id-12345', - refererInfo: {referer: 'http://examplereferer.com'} + refererInfo: { referer: 'http://examplereferer.com' } }; videoBidRequest = { @@ -127,7 +127,7 @@ describe('GamoshiAdapter', () => { 'sizes': [[300, 250], [300, 600]], 'transactionId': 'a123456789', 'bidId': '111', - refererInfo: {referer: 'http://examplereferer.com'} + refererInfo: { referer: 'http://examplereferer.com' } }; rtbResponse = { 'id': 'request-id-12345', @@ -135,8 +135,8 @@ describe('GamoshiAdapter', () => { 'cur': 'USD', 'ext': { 'utrk': [ - {'type': 'iframe', 'url': '//rtb.gamoshi.io/user/sync/1?gdpr=[GDPR]&consent=[CONSENT]&usp=[US_PRIVACY]'}, - {'type': 'image', 'url': '//rtb.gamoshi.io/user/sync/2'} + { 'type': 'iframe', 'url': '//rtb.gamoshi.io/user/sync/1?gdpr=[GDPR]&consent=[CONSENT]&usp=[US_PRIVACY]' }, + { 'type': 'image', 'url': '//rtb.gamoshi.io/user/sync/2' } ] }, 'seatbid': [ @@ -160,7 +160,7 @@ describe('GamoshiAdapter', () => { 'ext': { 'vast_url': 'http://my.vast.com', 'utrk': [ - {'type': 'iframe', 'url': '//p.partner1.io/user/sync/1'} + { 'type': 'iframe', 'url': '//p.partner1.io/user/sync/1' } ] } } @@ -185,7 +185,7 @@ describe('GamoshiAdapter', () => { 'w': 300, 'ext': { 'utrk': [ - {'type': 'image', 'url': '//p.partner2.io/user/sync/1'} + { 'type': 'image', 'url': '//p.partner2.io/user/sync/1' } ] } } @@ -289,19 +289,19 @@ describe('GamoshiAdapter', () => { describe('isBidRequestValid', () => { it('should validate supply-partner ID', () => { - expect(spec.isBidRequestValid({params: {}})).to.equal(false); - expect(spec.isBidRequestValid({params: {supplyPartnerId: 123}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supply_partner_id: 123}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supply_partner_id: '123'}})).to.equal(true); - expect(spec.isBidRequestValid({params: {inventory_id: 123}})).to.equal(true); - expect(spec.isBidRequestValid({params: {inventory_id: '123'}})).to.equal(true); - expect(spec.isBidRequestValid({params: {inventory_id: 'kukuk1212'}})).to.equal(false); + expect(spec.isBidRequestValid({ params: {} })).to.equal(false); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: 123 } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123' } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { supply_partner_id: 123 } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { supply_partner_id: '123' } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { inventory_id: 123 } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { inventory_id: '123' } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { inventory_id: 'kukuk1212' } })).to.equal(false); }); it('should validate RTB endpoint', () => { - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); // RTB endpoint has a default - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', rtbEndpoint: 123}})).to.equal(false); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123' } })).to.equal(true); // RTB endpoint has a default + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', rtbEndpoint: 123 } })).to.equal(false); expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', @@ -312,20 +312,20 @@ describe('GamoshiAdapter', () => { it('should validate bid floor', () => { // bidfloor can be omitted - should be valid - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123'}})).to.equal(true); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123' } })).to.equal(true); // bidfloor as string should be invalid - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: '123'}})).to.equal(true); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', bidfloor: '123' } })).to.equal(true); // bidfloor as zero should be invalid (not positive) - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: 0}})).to.equal(false); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', bidfloor: 0 } })).to.equal(false); // bidfloor as negative number should be invalid - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: -0.5}})).to.equal(false); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', bidfloor: -0.5 } })).to.equal(false); // bidfloor as positive number should be valid - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: 0.1}})).to.equal(true); - expect(spec.isBidRequestValid({params: {supplyPartnerId: '123', bidfloor: 1.5}})).to.equal(true); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', bidfloor: 0.1 } })).to.equal(true); + expect(spec.isBidRequestValid({ params: { supplyPartnerId: '123', bidfloor: 1.5 } })).to.equal(true); // // const getFloorResponse = {currency: 'USD', floor: 5}; // let testBidRequest = deepClone(bidRequest); @@ -372,8 +372,8 @@ describe('GamoshiAdapter', () => { response = spec.buildRequests([bidRequest], bidRequest); expect(Array.isArray(response)).to.equal(true); expect(response.length).to.equal(1); - const adUnit1 = Object.assign({}, utils.deepClone(bidRequest), {auctionId: '1', adUnitCode: 'a'}); - const adUnit2 = Object.assign({}, utils.deepClone(bidRequest), {auctionId: '1', adUnitCode: 'b'}); + const adUnit1 = Object.assign({}, utils.deepClone(bidRequest), { auctionId: '1', adUnitCode: 'a' }); + const adUnit2 = Object.assign({}, utils.deepClone(bidRequest), { auctionId: '1', adUnitCode: 'b' }); response = spec.buildRequests([adUnit1, adUnit2], bidRequest); expect(Array.isArray(response)).to.equal(true); expect(response.length).to.equal(2); @@ -548,11 +548,11 @@ describe('GamoshiAdapter', () => { describe('interpretResponse', () => { it('returns an empty array on missing response', () => { - let response = spec.interpretResponse(undefined, {bidRequest: bannerBidRequest}); + let response = spec.interpretResponse(undefined, { bidRequest: bannerBidRequest }); expect(Array.isArray(response)).to.equal(true); expect(response.length).to.equal(0); - response = spec.interpretResponse({}, {bidRequest: bannerBidRequest}); + response = spec.interpretResponse({}, { bidRequest: bannerBidRequest }); expect(Array.isArray(response)).to.equal(true); expect(response.length).to.equal(0); @@ -578,7 +578,7 @@ describe('GamoshiAdapter', () => { const mockOrtbRequest = { imp: [{ id: '1', tagid: bannerBidRequest.adUnitCode }] }; - const response = spec.interpretResponse({body: rtbResponse}, {data: mockOrtbRequest, bidRequest: bannerBidRequest}); + const response = spec.interpretResponse({ body: rtbResponse }, { data: mockOrtbRequest, bidRequest: bannerBidRequest }); expect(Array.isArray(response)).to.equal(true); // The ORTB converter handles response processing, just verify it returns an array }); @@ -587,13 +587,13 @@ describe('GamoshiAdapter', () => { const mockOrtbRequest = { imp: [{ id: '1', tagid: videoBidRequest.adUnitCode }] }; - const response = spec.interpretResponse({body: videoResponse}, {data: mockOrtbRequest, bidRequest: videoBidRequest}); + const response = spec.interpretResponse({ body: videoResponse }, { data: mockOrtbRequest, bidRequest: videoBidRequest }); expect(Array.isArray(response)).to.equal(true); // The ORTB converter handles response processing, just verify it returns an array }); it('aggregates user-sync pixels', () => { - const response = spec.getUserSyncs({}, [{body: rtbResponse}]); + const response = spec.getUserSyncs({}, [{ body: rtbResponse }]); expect(Array.isArray(response)).to.equal(true); expect(response.length).to.equal(4); expect(response[0].type).to.equal(rtbResponse.ext.utrk[0].type); @@ -612,12 +612,12 @@ describe('GamoshiAdapter', () => { const mockOrtbRequest = { imp: [{ id: '1', tagid: videoRequest.adUnitCode }] }; - const result = spec.interpretResponse({body: videoResponse}, {data: mockOrtbRequest, bidRequest: videoRequest}); + const result = spec.interpretResponse({ body: videoResponse }, { data: mockOrtbRequest, bidRequest: videoRequest }); expect(Array.isArray(result)).to.equal(true); }); it('validates in/existing of gdpr consent', () => { - let result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent, 'gamoshiCCPA'); + let result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent, 'gamoshiCCPA'); // print result expect(result).to.be.an('array'); @@ -626,14 +626,14 @@ describe('GamoshiAdapter', () => { expect(result[0].url).to.equal('https://rtb.gamoshi.io/pix/1275/scm?cb=1545900621675&gdpr=1&consent=consent%20string&us_privacy=gamoshiCCPA'); gdprConsent.gdprApplies = false; - result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent, 'gamoshiCCPA'); + result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent, 'gamoshiCCPA'); expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].type).to.equal('image'); expect(result[0].url).to.equal('https://rtb.gamoshi.io/pix/1275/scm?cb=1545900621675&gdpr=0&consent=&us_privacy=gamoshiCCPA'); videoResponse.ext.utrk[0].url = 'https://rtb.gamoshi.io/pix/1275/scm'; - result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent); + result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent); expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].type).to.equal('image'); @@ -641,21 +641,21 @@ describe('GamoshiAdapter', () => { }); it('validates existence of gdpr, gdpr consent and usp consent', () => { - let result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent, 'gamoshiCCPA'); + let result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent, 'gamoshiCCPA'); expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].type).to.equal('image'); expect(result[0].url).to.equal('https://rtb.gamoshi.io/pix/1275/scm?cb=1545900621675&gdpr=1&consent=consent%20string&us_privacy=gamoshiCCPA'); gdprConsent.gdprApplies = false; - result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent, ''); + result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent, ''); expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].type).to.equal('image'); expect(result[0].url).to.equal('https://rtb.gamoshi.io/pix/1275/scm?cb=1545900621675&gdpr=0&consent=&us_privacy='); videoResponse.ext.utrk[0].url = 'https://rtb.gamoshi.io/pix/1275/scm'; - result = spec.getUserSyncs({}, [{body: videoResponse}], gdprConsent); + result = spec.getUserSyncs({}, [{ body: videoResponse }], gdprConsent); expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].type).to.equal('image'); @@ -687,7 +687,7 @@ describe('GamoshiAdapter', () => { const mockOrtbRequest = { imp: [{ id: '1', tagid: videoBidRequest.adUnitCode }] }; - const response = spec.interpretResponse({body: videoResponseWithMeta}, {data: mockOrtbRequest, bidRequest: videoBidRequest}); + const response = spec.interpretResponse({ body: videoResponseWithMeta }, { data: mockOrtbRequest, bidRequest: videoBidRequest }); expect(Array.isArray(response)).to.equal(true); }); diff --git a/test/spec/modules/gemiusIdSystem_spec.js b/test/spec/modules/gemiusIdSystem_spec.js index 76c4549a321..7a2fa2ada7a 100644 --- a/test/spec/modules/gemiusIdSystem_spec.js +++ b/test/spec/modules/gemiusIdSystem_spec.js @@ -47,7 +47,15 @@ describe('GemiusId module', function () { consents: { 1: true, 2: false, - 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true, 11: true + 3: true, + 4: true, + 5: true, + 6: true, + 7: true, + 8: true, + 9: true, + 10: true, + 11: true } } } @@ -69,7 +77,7 @@ describe('GemiusId module', function () { const result = gemiusIdSubmodule.getId({}, { gdpr: gdprConsentData }); - expect(result).to.deep.equal({id: {id: null}}); + expect(result).to.deep.equal({ id: { id: null } }); }); it('should return callback on consent', function () { @@ -92,12 +100,12 @@ describe('GemiusId module', function () { expect(callback).to.be.a('function'); const testRuid = 'test-ruid-123'; - const statusOk = {status: 'ok'}; + const statusOk = { status: 'ok' }; callback(testRuid, statusOk); }); gemiusIdSubmodule.getId().callback((resultId) => { - expect(resultId).to.deep.equal({id: 'test-ruid-123'}); + expect(resultId).to.deep.equal({ id: 'test-ruid-123' }); expect(mockWindow.gemius_cmd.calledOnce).to.be.true; done(); }); @@ -134,7 +142,7 @@ describe('GemiusId module', function () { describe('decode', function () { it('should return object with gemiusId when value exists', function () { - const result = gemiusIdSubmodule.decode({id: 'test-gemius-id'}); + const result = gemiusIdSubmodule.decode({ id: 'test-gemius-id' }); expect(result).to.deep.equal({ gemiusId: 'test-gemius-id' }); diff --git a/test/spec/modules/genericAnalyticsAdapter_spec.js b/test/spec/modules/genericAnalyticsAdapter_spec.js index 72ec0e10dae..015bd9614f4 100644 --- a/test/spec/modules/genericAnalyticsAdapter_spec.js +++ b/test/spec/modules/genericAnalyticsAdapter_spec.js @@ -1,8 +1,8 @@ -import {defaultHandler, GenericAnalytics} from '../../../modules/genericAnalyticsAdapter.js'; +import { defaultHandler, GenericAnalytics } from '../../../modules/genericAnalyticsAdapter.js'; import * as events from 'src/events.js'; -import {EVENTS} from 'src/constants.js'; +import { EVENTS } from 'src/constants.js'; -const {AUCTION_INIT, BID_RESPONSE} = EVENTS; +const { AUCTION_INIT, BID_RESPONSE } = EVENTS; describe('Generic analytics', () => { describe('adapter', () => { @@ -98,12 +98,12 @@ describe('Generic analytics', () => { batchSize: 2 } }); - events.emit(AUCTION_INIT, {i: 0}); + events.emit(AUCTION_INIT, { i: 0 }); sinon.assert.notCalled(handler); - events.emit(BID_RESPONSE, {i: 0}); + events.emit(BID_RESPONSE, { i: 0 }); sinon.assert.calledWith(handler, sinon.match((arg) => { - return sinon.match({eventType: AUCTION_INIT, args: {i: 0}}).test(arg[0]) && - sinon.match({eventType: BID_RESPONSE, args: {i: 0}}).test(arg[1]); + return sinon.match({ eventType: AUCTION_INIT, args: { i: 0 } }).test(arg[0]) && + sinon.match({ eventType: BID_RESPONSE, args: { i: 0 } }).test(arg[1]); })); }); @@ -115,15 +115,15 @@ describe('Generic analytics', () => { } }); handler.throws(new Error()); - events.emit(AUCTION_INIT, {i: 0}); + events.emit(AUCTION_INIT, { i: 0 }); let recv; handler.resetHistory(); handler.resetBehavior(); handler.callsFake((arg) => { recv = arg; }); - events.emit(BID_RESPONSE, {i: 1}); - sinon.assert.match(recv, [sinon.match({eventType: BID_RESPONSE, args: {i: 1}})]) + events.emit(BID_RESPONSE, { i: 1 }); + sinon.assert.match(recv, [sinon.match({ eventType: BID_RESPONSE, args: { i: 1 } })]) }); it('should not cause infinite recursion, if handler triggers more events', () => { @@ -151,7 +151,7 @@ describe('Generic analytics', () => { handler } }); - [0, 1, 2].forEach(i => events.emit(BID_RESPONSE, {i})); + [0, 1, 2].forEach(i => events.emit(BID_RESPONSE, { i })); sinon.assert.calledOnce(handler); clock.tick(100); sinon.assert.calledTwice(handler); @@ -165,10 +165,10 @@ describe('Generic analytics', () => { handler } }); - [0, 1, 2].forEach(i => events.emit(BID_RESPONSE, {i})); + [0, 1, 2].forEach(i => events.emit(BID_RESPONSE, { i })); sinon.assert.calledOnce(handler); clock.tick(50); - events.emit(BID_RESPONSE, {i: 3}); + events.emit(BID_RESPONSE, { i: 3 }); sinon.assert.calledTwice(handler); clock.tick(100); sinon.assert.calledTwice(handler); @@ -204,8 +204,8 @@ describe('Generic analytics', () => { } } }); - events.emit(BID_RESPONSE, {prop: 'value', i: 0}); - sinon.assert.calledWith(handler, sinon.match(data => sinon.match({extra: 'data', prop: 'value'}).test(data[0]))); + events.emit(BID_RESPONSE, { prop: 'value', i: 0 }); + sinon.assert.calledWith(handler, sinon.match(data => sinon.match({ extra: 'data', prop: 'value' }).test(data[0]))); }); it('does not choke if an event handler throws', () => { @@ -223,9 +223,9 @@ describe('Generic analytics', () => { } }); events.emit(AUCTION_INIT, {}); - events.emit(BID_RESPONSE, {i: 0}); + events.emit(BID_RESPONSE, { i: 0 }); sinon.assert.calledOnce(handler); - sinon.assert.calledWith(handler, sinon.match(data => sinon.match({i: 0}).test(data[0]))); + sinon.assert.calledWith(handler, sinon.match(data => sinon.match({ i: 0 }).test(data[0]))); }); it('filters out events when their handler returns undefined', () => { @@ -240,10 +240,10 @@ describe('Generic analytics', () => { } } }); - events.emit(AUCTION_INIT, {i: 0}); - events.emit(BID_RESPONSE, {i: 1}); + events.emit(AUCTION_INIT, { i: 0 }); + events.emit(BID_RESPONSE, { i: 1 }); sinon.assert.calledOnce(handler); - sinon.assert.calledWith(handler, sinon.match(data => sinon.match({i: 0}).test(data[0]))); + sinon.assert.calledWith(handler, sinon.match(data => sinon.match({ i: 0 }).test(data[0]))); }); }); }); @@ -263,22 +263,22 @@ describe('Generic analytics', () => { }).forEach(([method, parse]) => { describe(`when HTTP method is ${method}`, () => { it('should send single event when batchSize is 1', () => { - const handler = defaultHandler({url, method, batchSize: 1, ajax}); - const payload = {i: 0}; + const handler = defaultHandler({ url, method, batchSize: 1, ajax }); + const payload = { i: 0 }; handler([payload, {}]); sinon.assert.calledWith(ajax, url, sinon.match.any, sinon.match(data => sinon.match(payload).test(parse(data))), - {method, keepalive: true} + { method, keepalive: true } ); }); it('should send multiple events when batchSize is greater than 1', () => { - const handler = defaultHandler({url, method, batchSize: 10, ajax}); - const payload = [{i: 0}, {i: 1}]; + const handler = defaultHandler({ url, method, batchSize: 10, ajax }); + const payload = [{ i: 0 }, { i: 1 }]; handler(payload); sinon.assert.calledWith(ajax, url, sinon.match.any, sinon.match(data => sinon.match(payload).test(parse(data))), - {method, keepalive: true} + { method, keepalive: true } ); }); }); diff --git a/test/spec/modules/geolocationRtdProvider_spec.js b/test/spec/modules/geolocationRtdProvider_spec.js index 26a9eef1e24..b34a6dd1953 100644 --- a/test/spec/modules/geolocationRtdProvider_spec.js +++ b/test/spec/modules/geolocationRtdProvider_spec.js @@ -1,16 +1,16 @@ -import {expect} from 'chai'; -import {geolocationSubmodule} from 'modules/geolocationRtdProvider.js'; +import { expect } from 'chai'; +import { geolocationSubmodule } from 'modules/geolocationRtdProvider.js'; import * as activityRules from 'src/activities/rules.js'; import 'src/prebid.js'; -import {PbPromise} from '../../../src/utils/promise.js'; -import {ACTIVITY_TRANSMIT_PRECISE_GEO} from '../../../src/activities/activities.js'; +import { PbPromise } from '../../../src/utils/promise.js'; +import { ACTIVITY_TRANSMIT_PRECISE_GEO } from '../../../src/activities/activities.js'; describe('Geolocation RTD Provider', function () { let sandbox; before(() => { if (!navigator.permissions) { - navigator.permissions = {mock: true, query: false} + navigator.permissions = { mock: true, query: false } } }); @@ -48,13 +48,13 @@ describe('Geolocation RTD Provider', function () { beforeEach(() => { onDone = sinon.stub(); permState = 'prompt'; - rtdConfig = {params: {}}; + rtdConfig = { params: {} }; clock = sandbox.useFakeTimers({ now: 11000, shouldClearNativeTimers: true }); sandbox.stub(navigator.geolocation, 'getCurrentPosition').value((cb) => { - cb({coords: {latitude: 1, longitude: 2}, timestamp: 1000}); + cb({ coords: { latitude: 1, longitude: 2 }, timestamp: 1000 }); }); permGiven = new Promise((resolve) => { sandbox.stub(navigator.permissions, 'query').value(() => { @@ -88,7 +88,7 @@ describe('Geolocation RTD Provider', function () { }); it(`should set geolocation`, async () => { - const requestBidObject = {ortb2Fragments: {global: {}}}; + const requestBidObject = { ortb2Fragments: { global: {} } }; geolocationSubmodule.getBidRequestData(requestBidObject, onDone, rtdConfig); await permGiven; clock.tick(300); @@ -112,7 +112,7 @@ describe('Geolocation RTD Provider', function () { beforeEach(setup); it(`should NOT set geo`, () => { - const req = {ortb2Fragments: {global: {}}}; + const req = { ortb2Fragments: { global: {} } }; geolocationSubmodule.getBidRequestData(req, onDone, rtdConfig); clock.tick(300); expect(req.ortb2Fragments.global.device?.geo).to.not.exist; diff --git a/test/spec/modules/getintentBidAdapter_spec.js b/test/spec/modules/getintentBidAdapter_spec.js index 35788f6f992..b2d836b54f7 100644 --- a/test/spec/modules/getintentBidAdapter_spec.js +++ b/test/spec/modules/getintentBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai' import { spec } from 'modules/getintentBidAdapter.js' -import {deepClone} from 'src/utils'; +import { deepClone } from 'src/utils'; describe('GetIntent Adapter Tests:', function () { const bidRequests = [{ @@ -133,7 +133,7 @@ describe('GetIntent Adapter Tests:', function () { const bidRequestWithFloor = deepClone(bidRequests[0]); bidRequestWithFloor.params.floor = 10 bidRequestWithFloor.params.cur = 'USD' - const getFloorResponse = {floor: 5, currency: 'EUR'}; + const getFloorResponse = { floor: 5, currency: 'EUR' }; bidRequestWithFloor.getFloor = () => getFloorResponse; const serverRequests = spec.buildRequests([bidRequestWithFloor]); diff --git a/test/spec/modules/glomexBidAdapter_spec.js b/test/spec/modules/glomexBidAdapter_spec.js index 8c53db8d605..e5352c5efac 100644 --- a/test/spec/modules/glomexBidAdapter_spec.js +++ b/test/spec/modules/glomexBidAdapter_spec.js @@ -114,8 +114,8 @@ describe('glomexBidAdapter', function () { describe('interpretResponse', function () { it('handles nobid responses', function () { - expect(spec.interpretResponse({body: {}}, {validBidRequests: []}).length).to.equal(0) - expect(spec.interpretResponse({body: []}, {validBidRequests: []}).length).to.equal(0) + expect(spec.interpretResponse({ body: {} }, { validBidRequests: [] }).length).to.equal(0) + expect(spec.interpretResponse({ body: [] }, { validBidRequests: [] }).length).to.equal(0) }) it('handles the server response', function () { diff --git a/test/spec/modules/goldbachBidAdapter_spec.js b/test/spec/modules/goldbachBidAdapter_spec.js index ac1207f6d19..caf0efec2ec 100644 --- a/test/spec/modules/goldbachBidAdapter_spec.js +++ b/test/spec/modules/goldbachBidAdapter_spec.js @@ -388,7 +388,7 @@ describe('GoldbachBidAdapter', function () { describe('interpretResponse', function () { it('should map response to valid bids (amount)', function () { const bidRequest = spec.buildRequests(validBidRequests, validBidderRequest); - const bidResponse = deepClone({body: validOrtbBidResponse}); + const bidResponse = deepClone({ body: validOrtbBidResponse }); const response = spec.interpretResponse(bidResponse, bidRequest); expect(response).to.exist; @@ -400,7 +400,7 @@ describe('GoldbachBidAdapter', function () { if (FEATURES.VIDEO) { it('should attach a custom video renderer ', function () { const bidRequest = spec.buildRequests(validBidRequests, validBidderRequest); - const bidResponse = deepClone({body: validOrtbBidResponse}); + const bidResponse = deepClone({ body: validOrtbBidResponse }); bidResponse.body.seatbid[0].bid[1].adm = ''; bidResponse.body.seatbid[0].bid[1].ext = { prebid: { type: 'video', meta: { type: 'video_outstream' } } }; const response = spec.interpretResponse(bidResponse, bidRequest); @@ -411,7 +411,7 @@ describe('GoldbachBidAdapter', function () { it('should set the player accordingly to config', function () { const bidRequest = spec.buildRequests(validBidRequests, validBidderRequest); - const bidResponse = deepClone({body: validOrtbBidResponse}); + const bidResponse = deepClone({ body: validOrtbBidResponse }); bidResponse.body.seatbid[0].bid[1].adm = ''; bidResponse.body.seatbid[0].bid[1].ext = { prebid: { type: 'video', meta: { type: 'video_outstream' } } }; validBidRequests[1].mediaTypes.video.playbackmethod = 1; @@ -427,7 +427,7 @@ describe('GoldbachBidAdapter', function () { it('should not attach a custom video renderer when VAST url/xml is missing', function () { const bidRequest = spec.buildRequests(validBidRequests, validBidderRequest); - const bidResponse = deepClone({body: validOrtbBidResponse}); + const bidResponse = deepClone({ body: validOrtbBidResponse }); bidResponse.body.seatbid[0].bid[1].adm = undefined; bidResponse.body.seatbid[0].bid[1].ext = { prebid: { type: 'video', meta: { type: 'video_outstream' } } }; const response = spec.interpretResponse(bidResponse, bidRequest); @@ -444,8 +444,9 @@ describe('GoldbachBidAdapter', function () { purpose: { consents: 1 } - }}; - const syncOptions = {pixelEnabled: true, iframeEnabled: true}; + } + }; + const syncOptions = { pixelEnabled: true, iframeEnabled: true }; const userSyncs = spec.getUserSyncs(syncOptions, {}, gdprConsent, {}); expect(userSyncs[0].type).to.equal('image'); @@ -459,8 +460,9 @@ describe('GoldbachBidAdapter', function () { purpose: { consents: 1 } - }}; - const syncOptions = {iframeEnabled: true}; + } + }; + const syncOptions = { iframeEnabled: true }; const userSyncs = spec.getUserSyncs(syncOptions, {}, gdprConsent, {}); expect(userSyncs[0].type).to.equal('iframe'); @@ -478,7 +480,7 @@ describe('GoldbachBidAdapter', function () { } } }; - const synOptions = {pixelEnabled: true, iframeEnabled: true}; + const synOptions = { pixelEnabled: true, iframeEnabled: true }; const userSyncs = spec.getUserSyncs(synOptions, {}, gdprConsent, {}); expect(userSyncs[0].url).to.contain(`https://ib.adnxs.com/getuid?${ENDPOINT_COOKIESYNC}`); expect(userSyncs[0].url).to.contain('xandrId=$UID'); diff --git a/test/spec/modules/goldfishAdsRtdProvider_spec.js b/test/spec/modules/goldfishAdsRtdProvider_spec.js index acbba5190df..515a51fc735 100755 --- a/test/spec/modules/goldfishAdsRtdProvider_spec.js +++ b/test/spec/modules/goldfishAdsRtdProvider_spec.js @@ -123,7 +123,7 @@ describe('goldfishAdsRtdProvider is a RTD provider that', function () { describe('has an updateUserData that', function () { it('properly transforms the response', function () { const userData = { - segment: [{id: '1'}, {id: '2'}], + segment: [{ id: '1' }, { id: '2' }], ext: { segtax: 4, } @@ -142,7 +142,7 @@ describe('goldfishAdsRtdProvider is a RTD provider that', function () { storage.setDataInLocalStorage(DATA_STORAGE_KEY, JSON.stringify({ targeting: { name: 'goldfishads.com', - segment: [{id: '1'}, {id: '2'}], + segment: [{ id: '1' }, { id: '2' }], ext: { segtax: 4, } diff --git a/test/spec/modules/gppControl_usstates_spec.js b/test/spec/modules/gppControl_usstates_spec.js index 1e9eb4176a8..2703678c782 100644 --- a/test/spec/modules/gppControl_usstates_spec.js +++ b/test/spec/modules/gppControl_usstates_spec.js @@ -1,4 +1,4 @@ -import {DEFAULT_SID_MAPPING, getSections, NORMALIZATIONS, normalizer} from '../../../modules/gppControl_usstates.js'; +import { DEFAULT_SID_MAPPING, getSections, NORMALIZATIONS, normalizer } from '../../../modules/gppControl_usstates.js'; describe('normalizer', () => { it('sets nullify fields to null', () => { @@ -23,7 +23,7 @@ describe('normalizer', () => { }); }); it('initializes scalar fields to null', () => { - const res = normalizer({}, {untouched: 0, f1: 0, f2: 0})({untouched: 0}); + const res = normalizer({}, { untouched: 0, f1: 0, f2: 0 })({ untouched: 0 }); expect(res).to.eql({ untouched: 0, f1: null, @@ -31,7 +31,7 @@ describe('normalizer', () => { }) }) it('initializes list fields to null-array with correct size', () => { - const res = normalizer({}, {'l1': 2, 'l2': 3})({}); + const res = normalizer({}, { 'l1': 2, 'l2': 3 })({}); expect(res).to.eql({ l1: [null, null], l2: [null, null, null] @@ -45,7 +45,7 @@ describe('normalizer', () => { 'arrays of the same size, with moves': [ [1, 2, 3], [1, 3, 2], - {2: 3, 3: 2} + { 2: 3, 3: 2 } ], 'original larger than normal': [ [1, 2, 3], @@ -54,7 +54,7 @@ describe('normalizer', () => { 'original larger than normal, with moves': [ [1, 2, 3], [null, 1], - {1: 2} + { 1: 2 } ], 'normal larger than original': [ [1, 2], @@ -63,7 +63,7 @@ describe('normalizer', () => { 'normal larger than original, with moves': [ [1, 2], [2, null, 2], - {2: [1, 3]} + { 2: [1, 3] } ], 'original is scalar': [ 'value', @@ -75,7 +75,7 @@ describe('normalizer', () => { ] }).forEach(([t, [from, to, move]]) => { it(`carries over values for list fields - ${t}`, () => { - const res = normalizer({move: {field: move || {}}}, {field: Array.isArray(to) ? to.length : 0})({field: from}); + const res = normalizer({ move: { field: move || {} } }, { field: Array.isArray(to) ? to.length : 0 })({ field: from }); expect(res.field).to.eql(to); }); }); @@ -92,17 +92,17 @@ describe('normalizer', () => { const res = normalizer({ nullify: ['nulled'], move: { - multi: {1: 2} + multi: { 1: 2 } }, fn - }, {nulled: 0, untouched: 0, multi: 2})(orig); + }, { nulled: 0, untouched: 0, multi: 2 })(orig); const transformed = { nulled: null, untouched: 0, multi: [null, 'a'] }; sinon.assert.calledWith(fn, orig, sinon.match(transformed)); - expect(res).to.eql(Object.assign({fn: true}, transformed)); + expect(res).to.eql(Object.assign({ fn: true }, transformed)); }); }); @@ -485,7 +485,7 @@ describe('getSections', () => { }); it('filters by sid', () => { - expect(getSections({sids: [8]})).to.eql([ + expect(getSections({ sids: [8] })).to.eql([ ['usca', [8], NORMALIZATIONS[8]] ]); }); diff --git a/test/spec/modules/gptPreAuction_spec.js b/test/spec/modules/gptPreAuction_spec.js index c369597ecbd..e9063b746aa 100644 --- a/test/spec/modules/gptPreAuction_spec.js +++ b/test/spec/modules/gptPreAuction_spec.js @@ -30,7 +30,7 @@ describe('GPT pre-auction module', () => { makeSlot({ code: 'slotCode4', divId: 'div5' }) ]; - const mockTargeting = {'/123456/header-bid-tag-0': {'hb_deal_rubicon': '1234', 'hb_deal': '1234', 'hb_pb': '0.53', 'hb_adid': '148018fe5e', 'hb_bidder': 'rubicon', 'foobar': '300x250', 'hb_pb_rubicon': '0.53', 'hb_adid_rubicon': '148018fe5e', 'hb_bidder_rubicon': 'rubicon', 'hb_deal_appnexus': '4321', 'hb_pb_appnexus': '0.1', 'hb_adid_appnexus': '567891011', 'hb_bidder_appnexus': 'appnexus'}} + const mockTargeting = { '/123456/header-bid-tag-0': { 'hb_deal_rubicon': '1234', 'hb_deal': '1234', 'hb_pb': '0.53', 'hb_adid': '148018fe5e', 'hb_bidder': 'rubicon', 'foobar': '300x250', 'hb_pb_rubicon': '0.53', 'hb_adid_rubicon': '148018fe5e', 'hb_bidder_rubicon': 'rubicon', 'hb_deal_appnexus': '4321', 'hb_pb_appnexus': '0.1', 'hb_adid_appnexus': '567891011', 'hb_bidder_appnexus': 'appnexus' } } const mockAuctionManager = { findBidByAdId(adId) { @@ -163,7 +163,7 @@ describe('GPT pre-auction module', () => { window.googletag.pubads().setSlots([ makeSlot({ code: '/12345,21212/slot', divId: 'div1' }), ]); - const adUnit = {code: '/12345,21212/slot'}; + const adUnit = { code: '/12345,21212/slot' }; expect(appendGptSlots([adUnit])).to.eql({ '/12345,21212/slot': '/12345,21212/slot' }) @@ -339,7 +339,7 @@ describe('GPT pre-auction module', () => { window.googletag.pubads().setSlots([ makeSlot({ code: '/12345,21212/slot', divId: 'div1' }), ]); - const adUnit = {code: '/12345,21212/slot'}; + const adUnit = { code: '/12345,21212/slot' }; makeBidRequestsHook(sinon.stub(), [adUnit]); sinon.assert.calledWith(customPreAuction, adUnit, '/12345/slot', adUnit.code); }); @@ -436,7 +436,7 @@ describe('GPT pre-auction module', () => { window.googletag.pubads().setSlots([ makeSlot({ code: '/12345,21212/slot', divId: 'div1' }), ]); - const adUnit = {code: '/12345,21212/slot'}; + const adUnit = { code: '/12345,21212/slot' }; makeBidRequestsHook(sinon.stub(), [adUnit]); expect(adUnit.ortb2Imp.ext.gpid).to.eql('/12345/slot'); }); @@ -464,7 +464,7 @@ describe('GPT pre-auction module', () => { it('should filter out adIds that do not map to any auction', () => { const auctionsIds = getAuctionsIdsFromTargeting({ ...mockTargeting, - 'au': {'hb_adid': 'missing'}, + 'au': { 'hb_adid': 'missing' }, }, mockAuctionManager); expect(auctionsIds).to.eql([mocksAuctions[0].auctionId, mocksAuctions[1].auctionId]); }) @@ -473,7 +473,7 @@ describe('GPT pre-auction module', () => { let auctionsIds = getAuctionsIdsFromTargeting({}, mockAuctionManager); expect(Array.isArray(auctionsIds)).to.equal(true); expect(auctionsIds).to.length(0); - auctionsIds = getAuctionsIdsFromTargeting({'/123456/header-bid-tag-0/bg': {'invalidContent': '123'}}, mockAuctionManager); + auctionsIds = getAuctionsIdsFromTargeting({ '/123456/header-bid-tag-0/bg': { 'invalidContent': '123' } }, mockAuctionManager); expect(Array.isArray(auctionsIds)).to.equal(true); expect(auctionsIds).to.length(0); }); diff --git a/test/spec/modules/gravitoIdSystem_spec.js b/test/spec/modules/gravitoIdSystem_spec.js index 9584f60c81d..095dd92cdd1 100644 --- a/test/spec/modules/gravitoIdSystem_spec.js +++ b/test/spec/modules/gravitoIdSystem_spec.js @@ -27,7 +27,7 @@ describe('gravitompId module', function () { it('should return the gravitompId when it exists in cookie', function () { getCookieStub.withArgs(cookieKey).returns(GRAVITOID_TEST_VALUE); const id = gravitoIdSystemSubmodule.getId(); - expect(id).to.be.deep.equal({id: {gravitompId: GRAVITOID_TEST_VALUE}}); + expect(id).to.be.deep.equal({ id: { gravitompId: GRAVITOID_TEST_VALUE } }); }); cookieTestCasesForEmpty.forEach(testCase => it('should return the gravitompId when it not exists in cookie', function () { @@ -40,7 +40,7 @@ describe('gravitompId module', function () { describe('decode()', function () { it('should return the gravitompId when it exists in cookie', function () { const decoded = gravitoIdSystemSubmodule.decode(GRAVITOID_TEST_OBJ); - expect(decoded).to.be.deep.equal({gravitompId: GRAVITOID_TEST_VALUE}); + expect(decoded).to.be.deep.equal({ gravitompId: GRAVITOID_TEST_VALUE }); }); it('should return the undefined when decode id is not "string"', function () { diff --git a/test/spec/modules/greenbidsAnalyticsAdapter_spec.js b/test/spec/modules/greenbidsAnalyticsAdapter_spec.js index fb59241553d..b6ac130a98d 100644 --- a/test/spec/modules/greenbidsAnalyticsAdapter_spec.js +++ b/test/spec/modules/greenbidsAnalyticsAdapter_spec.js @@ -107,7 +107,7 @@ describe('Greenbids Prebid AnalyticsAdapter Testing', function () { cpm: 0.08, currency: 'USD', ad: 'fake ad2', - params: {'placement ID': 12784} + params: { 'placement ID': 12784 } }, { auctionId: auctionId, diff --git a/test/spec/modules/greenbidsBidAdapter_spec.js b/test/spec/modules/greenbidsBidAdapter_spec.js index 00c0005fe16..6ff7777026e 100644 --- a/test/spec/modules/greenbidsBidAdapter_spec.js +++ b/test/spec/modules/greenbidsBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { spec, ENDPOINT_URL } from 'modules/greenbidsBidAdapter.js'; import { getScreenOrientation } from 'src/utils.js'; -import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; +import { getDevicePixelRatio } from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; const AD_SCRIPT = '"'; describe('greenbidsBidAdapter', () => { diff --git a/test/spec/modules/gridBidAdapter_spec.js b/test/spec/modules/gridBidAdapter_spec.js index 9fbc66c7975..a829580fc2c 100644 --- a/test/spec/modules/gridBidAdapter_spec.js +++ b/test/spec/modules/gridBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec, resetUserSync, getSyncUrl, storage } from 'modules/gridBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {ENDPOINT_DOMAIN, ENDPOINT_PROTOCOL} from '../../../modules/adpartnerBidAdapter.js'; +import { ENDPOINT_DOMAIN, ENDPOINT_PROTOCOL } from '../../../modules/adpartnerBidAdapter.js'; describe('TheMediaGrid Adapter', function () { const adapter = newBidder(spec); @@ -156,7 +156,7 @@ describe('TheMediaGrid Adapter', function () { genre: 'Adventure' } }; - const [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, ortb2: {site}}); + const [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, ortb2: { site } }); const payload = parseRequest(request.data); expect(payload.site.cat).to.deep.equal([...site.cat, ...site.pagecat]); expect(payload.site.content.genre).to.deep.equal(site.content.genre); @@ -178,7 +178,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequest.timeout, 'source': { 'tid': bidderRequest.ortb2.source.tid, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': fpdUserIdVal @@ -186,12 +186,12 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': bidRequests[0].bidId, 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, + 'ext': { 'divid': bidRequests[0].adUnitCode }, 'bidfloor': bidRequests[0].params.bidFloor, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }] }); @@ -215,7 +215,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequest.timeout, 'source': { 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': fpdUserIdVal @@ -223,21 +223,21 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': bidRequests[0].bidId, 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, + 'ext': { 'divid': bidRequests[0].adUnitCode }, 'bidfloor': bidRequests[0].params.bidFloor, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }, { 'id': bidRequests[1].bidId, 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, + 'ext': { 'divid': bidRequests[1].adUnitCode }, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }] }); @@ -261,7 +261,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequest.timeout, 'source': { 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': fpdUserIdVal @@ -269,26 +269,26 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': bidRequests[0].bidId, 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, + 'ext': { 'divid': bidRequests[0].adUnitCode }, 'bidfloor': bidRequests[0].params.bidFloor, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }, { 'id': bidRequests[1].bidId, 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, + 'ext': { 'divid': bidRequests[1].adUnitCode }, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }, { 'id': bidRequests[2].bidId, 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, + 'ext': { 'divid': bidRequests[2].adUnitCode }, 'video': { 'w': 400, 'h': 600, @@ -329,7 +329,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequest.timeout, 'source': { 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': fpdUserIdVal @@ -337,18 +337,22 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': bidMultiRequests[i].bidId, 'tagid': bidMultiRequests[i].params.uid, - 'ext': {'divid': bidMultiRequests[i].adUnitCode}, + 'ext': { 'divid': bidMultiRequests[i].adUnitCode }, ...(bidMultiRequests[i].params.bidFloor && { 'bidfloor': bidMultiRequests[i].params.bidFloor }), - ...(banner && { banner: { - 'w': banner.sizes[0][0], - 'h': banner.sizes[0][1], - 'format': banner.sizes.map(([w, h]) => ({ w, h })) - }}), - ...(video && { video: { - 'w': video.playerSize[0][0], - 'h': video.playerSize[0][1], - 'mimes': video.mimes - }}) + ...(banner && { + banner: { + 'w': banner.sizes[0][0], + 'h': banner.sizes[0][1], + 'format': banner.sizes.map(([w, h]) => ({ w, h })) + } + }), + ...(video && { + video: { + 'w': video.playerSize[0][0], + 'h': video.playerSize[0][1], + 'mimes': video.mimes + } + }) }] }); }); @@ -372,7 +376,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequest.timeout, 'source': { 'tid': bidderRequest.auctionId, - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': fpdUserIdVal @@ -380,26 +384,26 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': bidRequests[0].bidId, 'tagid': bidRequests[0].params.uid, - 'ext': {'divid': bidRequests[0].adUnitCode}, + 'ext': { 'divid': bidRequests[0].adUnitCode }, 'bidfloor': bidRequests[0].params.bidFloor, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }, { 'id': bidRequests[1].bidId, 'tagid': bidRequests[1].params.uid, - 'ext': {'divid': bidRequests[1].adUnitCode}, + 'ext': { 'divid': bidRequests[1].adUnitCode }, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }, { 'id': bidRequests[2].bidId, 'tagid': bidRequests[2].params.uid, - 'ext': {'divid': bidRequests[2].adUnitCode}, + 'ext': { 'divid': bidRequests[2].adUnitCode }, 'video': { 'w': 400, 'h': 600, @@ -408,11 +412,11 @@ describe('TheMediaGrid Adapter', function () { }, { 'id': bidRequests[3].bidId, 'tagid': bidRequests[3].params.uid, - 'ext': {'divid': bidRequests[3].adUnitCode}, + 'ext': { 'divid': bidRequests[3].adUnitCode }, 'banner': { 'w': 728, 'h': 90, - 'format': [{'w': 728, 'h': 90}] + 'format': [{ 'w': 728, 'h': 90 }] }, 'video': { 'w': 400, @@ -426,7 +430,7 @@ describe('TheMediaGrid Adapter', function () { }); it('if gdprConsent is present payload must have gdpr params', function () { - const gdprBidderRequest = Object.assign({gdprConsent: {consentString: 'AAA', gdprApplies: true}}, bidderRequest); + const gdprBidderRequest = Object.assign({ gdprConsent: { consentString: 'AAA', gdprApplies: true } }, bidderRequest); const [request] = spec.buildRequests(bidRequests, gdprBidderRequest); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); @@ -439,7 +443,7 @@ describe('TheMediaGrid Adapter', function () { }); it('if usPrivacy is present payload must have us_privacy param', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const [request] = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); @@ -450,7 +454,7 @@ describe('TheMediaGrid Adapter', function () { it('should add gpp information to the request via bidderRequest.gppConsent', function () { const consentString = 'abc1234'; - const gppBidderRequest = Object.assign({gppConsent: {gppString: consentString, applicableSections: [8]}}, bidderRequest); + const gppBidderRequest = Object.assign({ gppConsent: { gppString: consentString, applicableSections: [8] } }, bidderRequest); const [request] = spec.buildRequests(bidRequests, gppBidderRequest); const payload = JSON.parse(request.data); @@ -465,7 +469,7 @@ describe('TheMediaGrid Adapter', function () { const gppBidderRequest = { ...bidderRequest, ortb2: { - regs: {gpp: consentString, gpp_sid: [8]}, + regs: { gpp: consentString, gpp_sid: [8] }, ...bidderRequest.ortb2 } }; @@ -517,9 +521,9 @@ describe('TheMediaGrid Adapter', function () { screenHeight: 800, language: 'ru' }; - const ortb2 = {user: {ext: {device: ortb2UserExtDevice}}}; + const ortb2 = { user: { ext: { device: ortb2UserExtDevice } } }; - const [request] = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}); + const [request] = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); expect(payload).to.have.property('user'); @@ -559,7 +563,7 @@ describe('TheMediaGrid Adapter', function () { }); it('if content and segment is present in jwTargeting, payload must have right params', function () { - const jsContent = {id: 'test_jw_content_id'}; + const jsContent = { id: 'test_jw_content_id' }; const jsSegments = ['test_seg_1', 'test_seg_2']; const bidRequestsWithJwTargeting = bidRequests.map((bid) => { return Object.assign({ @@ -582,8 +586,8 @@ describe('TheMediaGrid Adapter', function () { it('should contain the keyword values if it present in ortb2.(site/user)', function () { const ortb2 = { - user: {'keywords': 'foo,any'}, - site: {'keywords': 'bar'} + user: { 'keywords': 'foo,any' }, + site: { 'keywords': 'bar' } }; const keywords = { 'site': { @@ -608,7 +612,7 @@ describe('TheMediaGrid Adapter', function () { } }; const bidRequestWithKW = { ...bidRequests[0], params: { ...bidRequests[0].params, keywords } } - const [request] = spec.buildRequests([bidRequestWithKW], {...bidderRequest, ortb2}); + const [request] = spec.buildRequests([bidRequestWithKW], { ...bidderRequest, ortb2 }); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); expect(payload.ext.keywords).to.deep.equal({ @@ -669,8 +673,8 @@ describe('TheMediaGrid Adapter', function () { someKey: 'another data' } ]; - const ortb2 = {user: {data: userData}}; - const [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, ortb2}); + const ortb2 = { user: { data: userData } }; + const [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, ortb2 }); const payload = parseRequest(request.data); expect(payload.user.data).to.deep.equal(userData); }); @@ -688,8 +692,8 @@ describe('TheMediaGrid Adapter', function () { ] } ]; - const ortb2 = {site: { content: { data: contentData } }}; - const [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, ortb2}); + const ortb2 = { site: { content: { data: contentData } } }; + const [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, ortb2 }); const payload = parseRequest(request.data); expect(payload.site.content.data).to.deep.equal(contentData); }); @@ -708,9 +712,9 @@ describe('TheMediaGrid Adapter', function () { someKey: 'another data' } ]; - const ortb2 = {user: {data: userData}}; + const ortb2 = { user: { data: userData } }; - const jsContent = {id: 'test_jw_content_id'}; + const jsContent = { id: 'test_jw_content_id' }; const jsSegments = ['test_seg_1', 'test_seg_2']; const bidRequestsWithJwTargeting = Object.assign({}, bidRequests[0], { rtd: { @@ -722,15 +726,15 @@ describe('TheMediaGrid Adapter', function () { } } }); - const [request] = spec.buildRequests([bidRequestsWithJwTargeting], {...bidderRequest, ortb2}); + const [request] = spec.buildRequests([bidRequestsWithJwTargeting], { ...bidderRequest, ortb2 }); const payload = parseRequest(request.data); expect(payload.user.data).to.deep.equal(userData); }); it('should have site.content.id filled from config ortb2.site.content.id', function () { const contentId = 'jw_abc'; - const ortb2 = {site: {content: {id: contentId}}}; - const [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, ortb2}); + const ortb2 = { site: { content: { id: contentId } } }; + const [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, ortb2 }); const payload = parseRequest(request.data); expect(payload.site.content.id).to.equal(contentId); }); @@ -771,7 +775,7 @@ describe('TheMediaGrid Adapter', function () { } }]; const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => { - return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: {...bid.ortb2Imp, ...ortb2Imp[ind]} } : {}); + return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: { ...bid.ortb2Imp, ...ortb2Imp[ind] } } : {}); }); const [request] = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest); expect(request.data).to.be.an('string'); @@ -812,7 +816,7 @@ describe('TheMediaGrid Adapter', function () { } }]; const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 2).map((bid, ind) => { - return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: {...bid.ortb2Imp, ...ortb2Imp[ind]} } : {}); + return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: { ...bid.ortb2Imp, ...ortb2Imp[ind] } } : {}); }); const [request] = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest); expect(request.data).to.be.an('string'); @@ -850,7 +854,7 @@ describe('TheMediaGrid Adapter', function () { } }]; const bidRequestsWithOrtb2Imp = bidRequests.slice(0, 3).map((bid, ind) => { - return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: {...bid.ortb2Imp, ...ortb2Imp[ind]} } : {}); + return Object.assign({}, bid, ortb2Imp[ind] ? { ortb2Imp: { ...bid.ortb2Imp, ...ortb2Imp[ind] } } : {}); }); const [request] = spec.buildRequests(bidRequestsWithOrtb2Imp, bidderRequest); expect(request.data).to.be.an('string'); @@ -906,7 +910,7 @@ describe('TheMediaGrid Adapter', function () { 'auctionId': 654645, }; const bidderRequestWithNumId = { - refererInfo: {page: 'https://example.com'}, + refererInfo: { page: 'https://example.com' }, bidderRequestId: 345345345, timeout: 3000, ortb2: { @@ -927,7 +931,7 @@ describe('TheMediaGrid Adapter', function () { 'tmax': bidderRequestWithNumId.timeout, 'source': { 'tid': '654645', - 'ext': {'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$'} + 'ext': { 'wrapper': 'Prebid_js', 'wrapper_version': '$prebid.version$' } }, 'user': { 'id': '2345543345' @@ -935,11 +939,11 @@ describe('TheMediaGrid Adapter', function () { 'imp': [{ 'id': '123123123', 'tagid': '1', - 'ext': {'divid': '1233'}, + 'ext': { 'divid': '1233' }, 'banner': { 'w': 300, 'h': 250, - 'format': [{'w': 300, 'h': 250}, {'w': 300, 'h': 600}] + 'format': [{ 'w': 300, 'h': 250 }, { 'w': 300, 'h': 600 }] } }] }); @@ -948,10 +952,10 @@ describe('TheMediaGrid Adapter', function () { }) it('tmax should be set as integer', function() { - let [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, timeout: '10'}); + let [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, timeout: '10' }); let payload = parseRequest(request.data); expect(payload.tmax).to.equal(10); - [request] = spec.buildRequests([bidRequests[0]], {...bidderRequest, timeout: 'ddqwdwdq'}); + [request] = spec.buildRequests([bidRequests[0]], { ...bidderRequest, timeout: 'ddqwdwdq' }); payload = parseRequest(request.data); expect(payload.tmax).to.equal(null); }) @@ -1002,7 +1006,7 @@ describe('TheMediaGrid Adapter', function () { it('should return the getFloor.floor value if it is greater than bidfloor', function () { const bidfloor = 0.80; const bidRequestsWithFloor = { ...bidRequest }; - bidRequestsWithFloor.params = Object.assign({bidFloor: bidfloor}, bidRequestsWithFloor.params); + bidRequestsWithFloor.params = Object.assign({ bidFloor: bidfloor }, bidRequestsWithFloor.params); const [request] = spec.buildRequests([bidRequestsWithFloor], bidderRequest); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); @@ -1011,7 +1015,7 @@ describe('TheMediaGrid Adapter', function () { it('should return the bidfloor value if it is greater than getFloor.floor', function () { const bidfloor = 1.80; const bidRequestsWithFloor = { ...bidRequest }; - bidRequestsWithFloor.params = Object.assign({bidFloor: bidfloor}, bidRequestsWithFloor.params); + bidRequestsWithFloor.params = Object.assign({ bidFloor: bidfloor }, bidRequestsWithFloor.params); const [request] = spec.buildRequests([bidRequestsWithFloor], bidderRequest); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); @@ -1020,7 +1024,7 @@ describe('TheMediaGrid Adapter', function () { it('should return the bidfloor string value if it is greater than getFloor.floor', function () { const bidfloor = '1.80'; const bidRequestsWithFloor = { ...bidRequest }; - bidRequestsWithFloor.params = Object.assign({bidFloor: bidfloor}, bidRequestsWithFloor.params); + bidRequestsWithFloor.params = Object.assign({ bidFloor: bidfloor }, bidRequestsWithFloor.params); const [request] = spec.buildRequests([bidRequestsWithFloor], bidderRequest); expect(request.data).to.be.an('string'); const payload = parseRequest(request.data); @@ -1031,14 +1035,14 @@ describe('TheMediaGrid Adapter', function () { describe('interpretResponse', function () { const responses = [ - {'bid': [{'impid': '659423fff799cb', 'adid': '13_14_4353', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, 'dealid': 11}], 'seat': '1'}, - {'bid': [{'impid': '4dff80cc4ee346', 'adid': '13_15_6454', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'impid': '5703af74d0472a', 'adid': '13_16_7654', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'impid': '2344da98f78b42', 'adid': '13_17_5433', 'price': 0, 'auid': 3, 'h': 250, 'w': 300}], 'seat': '1'}, - {'bid': [{'price': 0, 'adid': '13_18_34645', 'adm': '
test content 5
', 'h': 250, 'w': 300}], 'seat': '1'}, + { 'bid': [{ 'impid': '659423fff799cb', 'adid': '13_14_4353', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, 'dealid': 11 }], 'seat': '1' }, + { 'bid': [{ 'impid': '4dff80cc4ee346', 'adid': '13_15_6454', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300 }], 'seat': '1' }, + { 'bid': [{ 'impid': '5703af74d0472a', 'adid': '13_16_7654', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728 }], 'seat': '1' }, + { 'bid': [{ 'impid': '2344da98f78b42', 'adid': '13_17_5433', 'price': 0, 'auid': 3, 'h': 250, 'w': 300 }], 'seat': '1' }, + { 'bid': [{ 'price': 0, 'adid': '13_18_34645', 'adm': '
test content 5
', 'h': 250, 'w': 300 }], 'seat': '1' }, undefined, - {'bid': [], 'seat': '1'}, - {'seat': '1'}, + { 'bid': [], 'seat': '1' }, + { 'seat': '1' }, ]; it('should get correct bid response', function () { @@ -1075,7 +1079,7 @@ describe('TheMediaGrid Adapter', function () { } ]; - const result = spec.interpretResponse({'body': {'seatbid': [responses[0]]}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': [responses[0]] } }, request); expect(result).to.deep.equal(expectedResponse); }); @@ -1167,7 +1171,7 @@ describe('TheMediaGrid Adapter', function () { } ]; - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(0, 3)}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': responses.slice(0, 3) } }, request); expect(result).to.deep.equal(expectedResponse); }); @@ -1255,11 +1259,11 @@ describe('TheMediaGrid Adapter', function () { } ]; const response = [ - {'bid': [{'impid': '659423fff799cb', 'adid': '35_56_6454', 'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 11, content_type: 'video', w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'impid': '2bc598e42b6a', 'adid': '35_57_2344', 'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', content_type: 'video'}], 'seat': '2'}, - {'bid': [{'impid': '23312a43bc42', 'adid': '35_58_5345', 'price': 2.00, 'nurl': 'https://some_test_vast_url.com', 'auid': 13, content_type: 'video', 'adomain': ['example.com'], w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'impid': '112432ab4f34', 'adid': '35_59_56756', 'price': 1.80, 'adm': '\n<\/Ad>\n<\/VAST>', 'nurl': 'https://wrong_url.com', 'auid': 14, content_type: 'video', 'adomain': ['example.com'], w: 300, h: 600}], 'seat': '2'}, - {'bid': [{'impid': 'a74b342f8cd', 'adid': '35_60_523452', 'price': 1.50, 'nurl': '', 'auid': 15, content_type: 'video'}], 'seat': '2'} + { 'bid': [{ 'impid': '659423fff799cb', 'adid': '35_56_6454', 'price': 1.15, 'adm': '\n<\/Ad>\n<\/VAST>', 'auid': 11, content_type: 'video', w: 300, h: 600 }], 'seat': '2' }, + { 'bid': [{ 'impid': '2bc598e42b6a', 'adid': '35_57_2344', 'price': 1.00, 'adm': '\n<\/Ad>\n<\/VAST>', content_type: 'video' }], 'seat': '2' }, + { 'bid': [{ 'impid': '23312a43bc42', 'adid': '35_58_5345', 'price': 2.00, 'nurl': 'https://some_test_vast_url.com', 'auid': 13, content_type: 'video', 'adomain': ['example.com'], w: 300, h: 600 }], 'seat': '2' }, + { 'bid': [{ 'impid': '112432ab4f34', 'adid': '35_59_56756', 'price': 1.80, 'adm': '\n<\/Ad>\n<\/VAST>', 'nurl': 'https://wrong_url.com', 'auid': 14, content_type: 'video', 'adomain': ['example.com'], w: 300, h: 600 }], 'seat': '2' }, + { 'bid': [{ 'impid': 'a74b342f8cd', 'adid': '35_60_523452', 'price': 1.50, 'nurl': '', 'auid': 15, content_type: 'video' }], 'seat': '2' } ]; const [request] = spec.buildRequests(bidRequests); const expectedResponse = [ @@ -1338,7 +1342,7 @@ describe('TheMediaGrid Adapter', function () { }, ]; - const result = spec.interpretResponse({'body': {'seatbid': response}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': response } }, request); expect(result).to.deep.equal(expectedResponse); }); @@ -1379,17 +1383,17 @@ describe('TheMediaGrid Adapter', function () { } ]; const [request] = spec.buildRequests(bidRequests); - const result = spec.interpretResponse({'body': {'seatbid': responses.slice(2)}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': responses.slice(2) } }, request); expect(result.length).to.equal(0); }); it('complicated case', function () { const fullResponse = [ - {'bid': [{'impid': '2164be6358b9', 'adid': '32_52_7543', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, dealid: 11, 'ext': {'dsa': {'adrender': 1}}}], 'seat': '1'}, - {'bid': [{'impid': '4e111f1b66e4', 'adid': '32_54_4535', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300, dealid: 12}], 'seat': '1'}, - {'bid': [{'impid': '26d6f897b516', 'adid': '32_53_75467', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728}], 'seat': '1'}, - {'bid': [{'impid': '326bde7fbf69', 'adid': '32_54_12342', 'price': 0.15, 'adm': '
test content 4
', 'auid': 1, 'h': 600, 'w': 300}], 'seat': '1'}, - {'bid': [{'impid': '2234f233b22a', 'adid': '32_55_987686', 'price': 0.5, 'adm': '
test content 5
', 'auid': 2, 'h': 600, 'w': 350}], 'seat': '1'}, + { 'bid': [{ 'impid': '2164be6358b9', 'adid': '32_52_7543', 'price': 1.15, 'adm': '
test content 1
', 'auid': 1, 'h': 250, 'w': 300, dealid: 11, 'ext': { 'dsa': { 'adrender': 1 } } }], 'seat': '1' }, + { 'bid': [{ 'impid': '4e111f1b66e4', 'adid': '32_54_4535', 'price': 0.5, 'adm': '
test content 2
', 'auid': 2, 'h': 600, 'w': 300, dealid: 12 }], 'seat': '1' }, + { 'bid': [{ 'impid': '26d6f897b516', 'adid': '32_53_75467', 'price': 0.15, 'adm': '
test content 3
', 'auid': 1, 'h': 90, 'w': 728 }], 'seat': '1' }, + { 'bid': [{ 'impid': '326bde7fbf69', 'adid': '32_54_12342', 'price': 0.15, 'adm': '
test content 4
', 'auid': 1, 'h': 600, 'w': 300 }], 'seat': '1' }, + { 'bid': [{ 'impid': '2234f233b22a', 'adid': '32_55_987686', 'price': 0.5, 'adm': '
test content 5
', 'auid': 2, 'h': 600, 'w': 350 }], 'seat': '1' }, ]; const bidRequests = [ { @@ -1519,7 +1523,7 @@ describe('TheMediaGrid Adapter', function () { } ]; - const result = spec.interpretResponse({'body': {'seatbid': fullResponse}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': fullResponse } }, request); expect(result).to.deep.equal(expectedResponse); }); @@ -1583,7 +1587,7 @@ describe('TheMediaGrid Adapter', function () { } ]; - const result = spec.interpretResponse({'body': {'seatbid': [serverResponse]}}, request); + const result = spec.interpretResponse({ 'body': { 'seatbid': [serverResponse] } }, request); expect(result).to.deep.equal(expectedResponse); }); }); @@ -1613,14 +1617,14 @@ describe('TheMediaGrid Adapter', function () { pixelEnabled: true }); - expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); + expect(syncs).to.deep.equal({ type: 'image', url: syncUrl }); }); it('should not register the Emily iframe more than once', function () { let syncs = spec.getUserSyncs({ pixelEnabled: true }); - expect(syncs).to.deep.equal({type: 'image', url: syncUrl}); + expect(syncs).to.deep.equal({ type: 'image', url: syncUrl }); // when called again, should still have only been called once syncs = spec.getUserSyncs(); diff --git a/test/spec/modules/growadsBidAdapter_spec.js b/test/spec/modules/growadsBidAdapter_spec.js index 75c5d241a62..0ecc852d5e7 100644 --- a/test/spec/modules/growadsBidAdapter_spec.js +++ b/test/spec/modules/growadsBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/growadsBidAdapter.js'; import * as utils from '../../../src/utils.js'; -import {BANNER, NATIVE} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE } from '../../../src/mediaTypes.js'; describe('GrowAdvertising Adapter', function() { const ZONE_ID = 'unique-zone-id'; @@ -162,15 +162,15 @@ describe('GrowAdvertising Adapter', function() { ]; const requests = spec.buildRequests(validBids); - expect(requests[0].data).to.include({i: 0}); - expect(requests[1].data).to.include({i: 1}); + expect(requests[0].data).to.include({ i: 0 }); + expect(requests[1].data).to.include({ i: 1 }); }); }); describe('bid responses', function () { describe(BANNER, function () { it('should return complete bid response banner', function () { - const bids = spec.interpretResponse(serverResponseBanner, {bidRequest: bidRequests[0]}); + const bids = spec.interpretResponse(serverResponseBanner, { bidRequest: bidRequests[0] }); expect(bids).to.be.lengthOf(1); expect(bids[0].bidderCode).to.equal('growads'); @@ -190,7 +190,7 @@ describe('GrowAdvertising Adapter', function() { } }); - const bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]}); + const bids = spec.interpretResponse(response, { bidRequest: bidRequests[0] }); expect([]).to.be.lengthOf(0); }); @@ -201,14 +201,14 @@ describe('GrowAdvertising Adapter', function() { } }); - const bids = spec.interpretResponse(response, {bidRequest: bidRequests[0]}); + const bids = spec.interpretResponse(response, { bidRequest: bidRequests[0] }); expect([]).to.be.lengthOf(0); }); }); describe(NATIVE, function () { it('should return complete bid response banner', function () { - const bids = spec.interpretResponse(serverResponseNative, {bidRequest: bidRequests[1]}); + const bids = spec.interpretResponse(serverResponseNative, { bidRequest: bidRequests[1] }); expect(bids).to.be.lengthOf(1); expect(bids[0].bidderCode).to.equal('growads'); diff --git a/test/spec/modules/growthCodeIdSystem_spec.js b/test/spec/modules/growthCodeIdSystem_spec.js index 537a77c5b42..79c75df368d 100644 --- a/test/spec/modules/growthCodeIdSystem_spec.js +++ b/test/spec/modules/growthCodeIdSystem_spec.js @@ -2,9 +2,9 @@ import { growthCodeIdSubmodule } from 'modules/growthCodeIdSystem.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; import { uspDataHandler } from 'src/adapterManager.js'; -import {expect} from 'chai'; -import {getStorageManager} from '../../../src/storageManager.js'; -import {MODULE_TYPE_UID} from '../../../src/activities/modules.js'; +import { expect } from 'chai'; +import { getStorageManager } from '../../../src/storageManager.js'; +import { MODULE_TYPE_UID } from '../../../src/activities/modules.js'; const MODULE_NAME = 'growthCodeId'; const EIDS = '[{"source":"domain.com","uids":[{"id":"8212212191539393121","ext":{"stype":"ppuid"}}]}]'; @@ -15,11 +15,13 @@ const GCID_EID_EID = '{"id": [{"source": "growthcode.io", "uids": [{"atype": 3," const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: MODULE_NAME }); -const getIdParams = {params: { - pid: 'TEST01', - publisher_id: '_sharedid', - publisher_id_storage: 'html5', -}}; +const getIdParams = { + params: { + pid: 'TEST01', + publisher_id: '_sharedid', + publisher_id_storage: 'html5', + } +}; describe('growthCodeIdSystem', () => { let logErrorStub; @@ -55,25 +57,31 @@ describe('growthCodeIdSystem', () => { it('test return of the GCID and an additional EID', function () { let ids; - ids = growthCodeIdSubmodule.getId({params: { - customerEids: 'customerEids', - }}); + ids = growthCodeIdSubmodule.getId({ + params: { + customerEids: 'customerEids', + } + }); expect(ids).to.deep.equal(JSON.parse(GCID_EID_EID)); }); it('test return of the GCID and an additional EID (bad Local Store name)', function () { let ids; - ids = growthCodeIdSubmodule.getId({params: { - customerEids: 'customerEidsBad', - }}); + ids = growthCodeIdSubmodule.getId({ + params: { + customerEids: 'customerEidsBad', + } + }); expect(ids).to.deep.equal(JSON.parse(GCID_EID)); }); it('test decode function)', function () { let ids; - ids = growthCodeIdSubmodule.decode(GCID, {params: { - customerEids: 'customerEids', - }}); + ids = growthCodeIdSubmodule.decode(GCID, { + params: { + customerEids: 'customerEids', + } + }); expect(ids).to.deep.equal(JSON.parse('{"growthCodeId":"' + GCID + '"}')); }); }) diff --git a/test/spec/modules/growthCodeRtdProvider_spec.js b/test/spec/modules/growthCodeRtdProvider_spec.js index 47213a3ddd9..76374f5f934 100644 --- a/test/spec/modules/growthCodeRtdProvider_spec.js +++ b/test/spec/modules/growthCodeRtdProvider_spec.js @@ -1,5 +1,5 @@ -import {config} from 'src/config.js'; -import {growthCodeRtdProvider} from '../../../modules/growthCodeRtdProvider.js'; +import { config } from 'src/config.js'; +import { growthCodeRtdProvider } from '../../../modules/growthCodeRtdProvider.js'; import sinon from 'sinon'; import * as ajaxLib from 'src/ajax.js'; @@ -85,26 +85,29 @@ describe('growthCodeRtdProvider', function() { 'client_a': { 'user': - {'ext': - {'data': - {'eids': [ - {'source': 'test.com', - 'uids': [ - { - 'id': '4254074976bb6a6d970f5f693bd8a75c', - 'atype': 3, - 'ext': { - 'stype': 'hemmd5'} - }, { - 'id': 'd0ee291572ffcfba0bf7edb2b1c90ca7c32d255e5040b8b50907f5963abb1898', - 'atype': 3, - 'ext': { - 'stype': 'hemsha256' + { + 'ext': + { + 'data': + { + 'eids': [ + { + 'source': 'test.com', + 'uids': [ + { + 'id': '4254074976bb6a6d970f5f693bd8a75c', + 'atype': 3, + 'ext': { 'stype': 'hemmd5' } + }, { + 'id': 'd0ee291572ffcfba0bf7edb2b1c90ca7c32d255e5040b8b50907f5963abb1898', + 'atype': 3, + 'ext': { + 'stype': 'hemsha256' + } } - } - ] - } - ] + ] + } + ] } } } @@ -118,7 +121,7 @@ describe('growthCodeRtdProvider', function() { 'parameters': JSON.stringify(gcData) }] - const bidConfig = {ortb2Fragments: {bidder: {}}}; + const bidConfig = { ortb2Fragments: { bidder: {} } }; growthCodeRtdProvider.addData(bidConfig, payload) expect(bidConfig.ortb2Fragments.bidder).to.deep.equal(gcData) diff --git a/test/spec/modules/gumgumBidAdapter_spec.js b/test/spec/modules/gumgumBidAdapter_spec.js index 1ceaf4f2646..bfb361cdc8a 100644 --- a/test/spec/modules/gumgumBidAdapter_spec.js +++ b/test/spec/modules/gumgumBidAdapter_spec.js @@ -100,6 +100,39 @@ describe('gumgumAdapter', function () { describe('buildRequests', function () { const sizesArray = [[300, 250], [300, 600]]; + const id5Eid = { + source: 'id5-sync.com', + uids: [{ + id: 'uid-string', + ext: { + linkType: 2 + } + }] + }; + const pubProvidedIdEids = [ + { + uids: [ + { + ext: { + stype: 'ppuid', + }, + id: 'aac4504f-ef89-401b-a891-ada59db44336', + }, + ], + source: 'audigent.com', + }, + { + uids: [ + { + ext: { + stype: 'ppuid', + }, + id: 'y-zqTHmW9E2uG3jEETC6i6BjGcMhPXld2F~A', + }, + ], + source: 'crwdcntrl.net', + }, + ]; const bidderRequest = { ortb2: { site: { @@ -136,38 +169,7 @@ describe('gumgumAdapter', function () { sizes: sizesArray } }, - userId: { - id5id: { - uid: 'uid-string', - ext: { - linkType: 2 - } - } - }, - pubProvidedId: [ - { - uids: [ - { - ext: { - stype: 'ppuid', - }, - id: 'aac4504f-ef89-401b-a891-ada59db44336', - }, - ], - source: 'sonobi.com', - }, - { - uids: [ - { - ext: { - stype: 'ppuid', - }, - id: 'y-zqTHmW9E2uG3jEETC6i6BjGcMhPXld2F~A', - }, - ], - source: 'aol.com', - }, - ], + userIdAsEids: [id5Eid, ...pubProvidedIdEids], adUnitCode: 'adunit-code', sizes: sizesArray, bidId: '30b31c1838de1e', @@ -227,13 +229,139 @@ describe('gumgumAdapter', function () { it('should set pubProvidedId if the uid and pubProvidedId are available', function () { const request = { ...bidRequests[0] }; const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pubProvidedId).to.equal(JSON.stringify(bidRequests[0].userId.pubProvidedId)); + expect(bidRequest.data.pubProvidedId).to.equal(JSON.stringify(pubProvidedIdEids)); + }); + it('should filter pubProvidedId entries by allowed sources', function () { + const filteredRequest = { + ...bidRequests[0], + userIdAsEids: [ + { + source: 'audigent.com', + uids: [{ id: 'ppid-1', ext: { stype: 'ppuid' } }] + }, + { + source: 'sonobi.com', + uids: [{ id: 'ppid-2', ext: { stype: 'ppuid' } }] + } + ] + }; + const bidRequest = spec.buildRequests([filteredRequest])[0]; + const pubProvidedIds = JSON.parse(bidRequest.data.pubProvidedId); + expect(pubProvidedIds.length).to.equal(1); + expect(pubProvidedIds[0].source).to.equal('audigent.com'); + }); + it('should not set pubProvidedId when all sources are filtered out', function () { + const filteredRequest = { + ...bidRequests[0], + userIdAsEids: [{ + source: 'sonobi.com', + uids: [{ id: 'ppid-2', ext: { stype: 'ppuid' } }] + }] + }; + const bidRequest = spec.buildRequests([filteredRequest])[0]; + expect(bidRequest.data.pubProvidedId).to.equal(undefined); }); it('should set id5Id and id5IdLinkType if the uid and linkType are available', function () { const request = { ...bidRequests[0] }; const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.id5Id).to.equal(bidRequests[0].userId.id5id.uid); - expect(bidRequest.data.id5IdLinkType).to.equal(bidRequests[0].userId.id5id.ext.linkType); + expect(bidRequest.data.id5Id).to.equal(id5Eid.uids[0].id); + expect(bidRequest.data.id5IdLinkType).to.equal(id5Eid.uids[0].ext.linkType); + }); + it('should use bidderRequest.ortb2.user.ext.eids when bid-level eids are not available', function () { + const request = { ...bidRequests[0], userIdAsEids: undefined }; + const fakeBidderRequest = { + ...bidderRequest, + ortb2: { + ...bidderRequest.ortb2, + user: { + ext: { + eids: [{ + source: 'liveramp.com', + uids: [{ + id: 'fallback-idl-env' + }] + }] + } + } + } + }; + const bidRequest = spec.buildRequests([request], fakeBidderRequest)[0]; + expect(bidRequest.data.idl_env).to.equal('fallback-idl-env'); + }); + it('should prioritize bidderRequest.ortb2.user.ext.eids over bid-level eids', function () { + const request = { + ...bidRequests[0], + userIdAsEids: [{ + source: 'liveramp.com', + uids: [{ id: 'bid-level-idl-env' }] + }] + }; + const fakeBidderRequest = { + ...bidderRequest, + ortb2: { + ...bidderRequest.ortb2, + user: { + ext: { + eids: [{ + source: 'liveramp.com', + uids: [{ id: 'ortb2-level-idl-env' }] + }] + } + } + } + }; + const bidRequest = spec.buildRequests([request], fakeBidderRequest)[0]; + expect(bidRequest.data.idl_env).to.equal('ortb2-level-idl-env'); + }); + it('should keep identity output consistent for prebid10 ortb2 eids input', function () { + const request = { ...bidRequests[0], userIdAsEids: undefined }; + const fakeBidderRequest = { + ...bidderRequest, + ortb2: { + ...bidderRequest.ortb2, + user: { + ext: { + eids: [ + { + source: 'uidapi.com', + uids: [{ id: 'uid2-token', atype: 3 }] + }, + { + source: 'liveramp.com', + uids: [{ id: 'idl-envelope', atype: 1 }] + }, + { + source: 'adserver.org', + uids: [{ id: 'tdid-value', atype: 1, ext: { rtiPartner: 'TDID' } }] + }, + { + source: 'id5-sync.com', + uids: [{ id: 'id5-value', atype: 1, ext: { linkType: 2 } }] + }, + { + source: 'audigent.com', + uids: [{ id: 'ppid-1', atype: 1, ext: { stype: 'ppuid' } }] + }, + { + source: 'sonobi.com', + uids: [{ id: 'ppid-2', atype: 1, ext: { stype: 'ppuid' } }] + } + ] + } + } + } + }; + const bidRequest = spec.buildRequests([request], fakeBidderRequest)[0]; + + // Expected identity payload shape from legacy GumGum request fields. + expect(bidRequest.data.uid2).to.equal('uid2-token'); + expect(bidRequest.data.idl_env).to.equal('idl-envelope'); + expect(bidRequest.data.tdid).to.equal('tdid-value'); + expect(bidRequest.data.id5Id).to.equal('id5-value'); + expect(bidRequest.data.id5IdLinkType).to.equal(2); + const pubProvidedId = JSON.parse(bidRequest.data.pubProvidedId); + expect(pubProvidedId.length).to.equal(1); + expect(pubProvidedId[0].source).to.equal('audigent.com'); }); it('should set pubId param if found', function () { @@ -298,6 +426,266 @@ describe('gumgumAdapter', function () { const bidRequest = spec.buildRequests([request], bidderRequest)[0]; expect(bidRequest.data).to.have.property('curl', 'http://pub.com/news'); }); + + describe('content metadata extraction', function() { + it('should extract all site.content fields', function() { + const ortb2WithContent = { + site: { + content: { + id: 'content-id-123', + episode: 5, + title: 'Test Episode Title', + series: 'Test Series', + season: 'Season 2', + genre: 'Comedy', + contentrating: 'PG-13', + userrating: '4.5', + context: 1, + livestream: 1, + len: 1800, + language: 'en', + url: 'https://example.com/content', + cattax: 6, + prodq: 2, + qagmediarating: 1, + keywords: 'keyword1,keyword2,keyword3', + cat: ['IAB1-1', 'IAB1-2', 'IAB1-3'], + producer: { + id: 'producer-123', + name: 'Test Producer' + }, + channel: { + id: 'channel-123', + name: 'Test Channel', + domain: 'testchannel.com' + }, + network: { + name: 'Test Network' + } + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ...bidderRequest, ortb2: ortb2WithContent })[0]; + + expect(bidRequest.data.itype).to.equal('site'); + expect(bidRequest.data.cid).to.equal('content-id-123'); + expect(bidRequest.data.cepisode).to.equal(5); + expect(bidRequest.data.ctitle).to.equal('Test Episode Title'); + expect(bidRequest.data.cseries).to.equal('Test Series'); + expect(bidRequest.data.cseason).to.equal('Season 2'); + expect(bidRequest.data.cgenre).to.equal('Comedy'); + expect(bidRequest.data.crating).to.equal('PG-13'); + expect(bidRequest.data.cur).to.equal('4.5'); + expect(bidRequest.data.cctx).to.equal(1); + expect(bidRequest.data.clive).to.equal(1); + expect(bidRequest.data.clen).to.equal(1800); + expect(bidRequest.data.clang).to.equal('en'); + expect(bidRequest.data.curl).to.equal('https://example.com/content'); + expect(bidRequest.data.cattax).to.equal(6); + expect(bidRequest.data.cprodq).to.equal(2); + expect(bidRequest.data.cqag).to.equal(1); + expect(bidRequest.data.ckw).to.equal('keyword1,keyword2,keyword3'); + expect(bidRequest.data.ccat).to.equal('IAB1-1,IAB1-2,IAB1-3'); + expect(bidRequest.data.cpid).to.equal('producer-123'); + expect(bidRequest.data.cpname).to.equal('Test Producer'); + expect(bidRequest.data.cchannelid).to.equal('channel-123'); + expect(bidRequest.data.cchannel).to.equal('Test Channel'); + expect(bidRequest.data.cchanneldomain).to.equal('testchannel.com'); + expect(bidRequest.data.cnetwork).to.equal('Test Network'); + }); + + it('should extract app.content fields when site.content is not present', function() { + const ortb2WithAppContent = { + app: { + content: { + id: 'app-content-id', + title: 'App Content Title', + series: 'App Series', + url: 'https://example.com/app-content' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2: ortb2WithAppContent })[0]; + + expect(bidRequest.data.itype).to.equal('app'); + expect(bidRequest.data.cid).to.equal('app-content-id'); + expect(bidRequest.data.ctitle).to.equal('App Content Title'); + expect(bidRequest.data.cseries).to.equal('App Series'); + expect(bidRequest.data.curl).to.equal('https://example.com/app-content'); + }); + + it('should prioritize site.content over app.content', function() { + const ortb2WithBoth = { + site: { + content: { + id: 'site-content-id', + title: 'Site Content' + } + }, + app: { + content: { + id: 'app-content-id', + title: 'App Content' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2: ortb2WithBoth })[0]; + + expect(bidRequest.data.itype).to.equal('site'); + expect(bidRequest.data.cid).to.equal('site-content-id'); + expect(bidRequest.data.ctitle).to.equal('Site Content'); + }); + + it('should handle keywords as an array', function() { + const ortb2 = { + site: { + content: { + keywords: ['keyword1', 'keyword2', 'keyword3'] + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.ckw).to.equal('keyword1,keyword2,keyword3'); + }); + + it('should handle keywords as a string', function() { + const ortb2 = { + site: { + content: { + keywords: 'keyword1,keyword2,keyword3' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.ckw).to.equal('keyword1,keyword2,keyword3'); + }); + + it('should not include content params when content object is missing', function() { + const ortb2 = { + site: { + page: 'https://example.com' + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data).to.not.have.property('cid'); + expect(bidRequest.data).to.not.have.property('ctitle'); + expect(bidRequest.data).to.not.have.property('curl'); + }); + + it('should not include undefined or null content fields', function() { + const ortb2 = { + site: { + content: { + id: 'content-123', + title: undefined, + series: null, + season: '' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.cid).to.equal('content-123'); + expect(bidRequest.data).to.not.have.property('ctitle'); + expect(bidRequest.data).to.not.have.property('cseries'); + expect(bidRequest.data).to.not.have.property('cseason'); + }); + + it('should handle zero values for numeric fields', function() { + const ortb2 = { + site: { + content: { + episode: 0, + context: 0, + livestream: 0, + len: 0, + cattax: 0, + prodq: 0, + qagmediarating: 0 + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.cepisode).to.equal(0); + expect(bidRequest.data.cctx).to.equal(0); + expect(bidRequest.data.clive).to.equal(0); + expect(bidRequest.data.clen).to.equal(0); + expect(bidRequest.data.cattax).to.equal(0); + expect(bidRequest.data.cprodq).to.equal(0); + expect(bidRequest.data.cqag).to.equal(0); + }); + + it('should handle empty arrays for cat', function() { + const ortb2 = { + site: { + content: { + cat: [] + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data).to.not.have.property('ccat'); + }); + + it('should handle partial producer data', function() { + const ortb2 = { + site: { + content: { + producer: { + id: 'producer-id-only' + } + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.cpid).to.equal('producer-id-only'); + expect(bidRequest.data).to.not.have.property('cpname'); + }); + + it('should handle episode as string', function() { + const ortb2 = { + site: { + content: { + episode: 'S01E05' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ortb2 })[0]; + + expect(bidRequest.data.cepisode).to.equal('S01E05'); + }); + + it('should not override existing curl from irisid extraction', function() { + const ortb2 = { + site: { + content: { + url: 'https://content-url.com' + } + } + }; + const request = { ...bidRequests[0] }; + const bidRequest = spec.buildRequests([request], { ...bidderRequest, ortb2 })[0]; + + expect(bidRequest.data.curl).to.equal('https://content-url.com'); + }); + }); it('should not set the iriscat param when not found', function () { const request = { ...bidRequests[0] } const bidRequest = spec.buildRequests([request])[0]; @@ -316,7 +704,8 @@ describe('gumgumAdapter', function () { }); it('should set the global placement id (gpid) if in adserver property', function () { - const req = { ...bidRequests[0], + const req = { + ...bidRequests[0], ortb2Imp: { ext: { gpid: '/17037559/jeusol/jeusol_D_1', @@ -327,13 +716,15 @@ describe('gumgumAdapter', function () { } } } - } } + } + } const bidRequest = spec.buildRequests([req])[0]; expect(bidRequest.data).to.have.property('gpid'); expect(bidRequest.data.gpid).to.equal('/17037559/jeusol/jeusol_D_1'); }); it('should set ae value to 1 for PAAPI', function () { - const req = { ...bidRequests[0], + const req = { + ...bidRequests[0], ortb2Imp: { ext: { ae: 1, @@ -344,7 +735,8 @@ describe('gumgumAdapter', function () { } } } - } } + } + } const bidRequest = spec.buildRequests([req])[0]; expect(bidRequest.data).to.have.property('ae'); expect(bidRequest.data.ae).to.equal(true); @@ -614,7 +1006,7 @@ describe('gumgumAdapter', function () { it('should set pubProvidedId if the uid and pubProvidedId are available', function () { const request = { ...bidRequests[0] }; const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.pubProvidedId).to.equal(JSON.stringify(bidRequests[0].userId.pubProvidedId)); + expect(bidRequest.data.pubProvidedId).to.equal(JSON.stringify(pubProvidedIdEids)); }); it('should add gdpr consent parameters if gdprConsent is present', function () { @@ -714,14 +1106,40 @@ describe('gumgumAdapter', function () { expect(bidRequest.data.uspConsent).to.eq(uspConsentObj.uspConsent); }); it('should add a tdid parameter if request contains unified id from TradeDesk', function () { - const unifiedId = { - 'userId': { - 'tdid': 'tradedesk-id' - } - } - const request = Object.assign(unifiedId, bidRequests[0]); + const tdidEid = { + source: 'adserver.org', + uids: [{ + id: 'tradedesk-id', + ext: { + rtiPartner: 'TDID' + } + }] + }; + const request = Object.assign({}, bidRequests[0], { userIdAsEids: [...bidRequests[0].userIdAsEids, tdidEid] }); + const bidRequest = spec.buildRequests([request])[0]; + expect(bidRequest.data.tdid).to.eq(tdidEid.uids[0].id); + }); + it('should add a tdid parameter when TDID uid is not the first uid in adserver.org', function () { + const tdidEid = { + source: 'adserver.org', + uids: [ + { + id: 'non-tdid-first', + ext: { + rtiPartner: 'NOT_TDID' + } + }, + { + id: 'tradedesk-id', + ext: { + rtiPartner: 'TDID' + } + } + ] + }; + const request = Object.assign({}, bidRequests[0], { userIdAsEids: [tdidEid] }); const bidRequest = spec.buildRequests([request])[0]; - expect(bidRequest.data.tdid).to.eq(unifiedId.userId.tdid); + expect(bidRequest.data.tdid).to.eq('tradedesk-id'); }); it('should not add a tdid parameter if unified id is not found', function () { const request = spec.buildRequests(bidRequests)[0]; @@ -729,7 +1147,8 @@ describe('gumgumAdapter', function () { }); it('should send IDL envelope ID if available', function () { const idl_env = 'abc123'; - const request = { ...bidRequests[0], userId: { idl_env } }; + const idlEid = { source: 'liveramp.com', uids: [{ id: idl_env }] }; + const request = { ...bidRequests[0], userIdAsEids: [idlEid] }; const bidRequest = spec.buildRequests([request])[0]; expect(bidRequest.data).to.have.property('idl_env'); @@ -743,7 +1162,8 @@ describe('gumgumAdapter', function () { }); it('should add a uid2 parameter if request contains uid2 id', function () { const uid2 = { id: 'sample-uid2' }; - const request = { ...bidRequests[0], userId: { uid2 } }; + const uid2Eid = { source: 'uidapi.com', uids: [{ id: uid2.id }] }; + const request = { ...bidRequests[0], userIdAsEids: [uid2Eid] }; const bidRequest = spec.buildRequests([request])[0]; expect(bidRequest.data).to.have.property('uid2'); @@ -868,7 +1288,7 @@ describe('gumgumAdapter', function () { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, ip: '127.0.0.1', ipv6: '51dc:5e20:fd6a:c955:66be:03b4:dfa3:35b2', sua: suaObject @@ -1083,7 +1503,7 @@ describe('gumgumAdapter', function () { it('request size that matches response size for in-slot', function () { const request = { ...bidRequest }; const body = { ...serverResponse }; - const expectedSize = [[ 320, 50 ], [300, 600], [300, 250]]; + const expectedSize = [[320, 50], [300, 600], [300, 250]]; let result; request.pi = 3; body.ad.width = 300; diff --git a/test/spec/modules/h12mediaBidAdapter_spec.js b/test/spec/modules/h12mediaBidAdapter_spec.js index a4e5a7926c0..29b09315089 100644 --- a/test/spec/modules/h12mediaBidAdapter_spec.js +++ b/test/spec/modules/h12mediaBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/h12mediaBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory'; -import {clearCache} from '../../../libraries/boundingClientRect/boundingClientRect.js'; +import { expect } from 'chai'; +import { spec } from 'modules/h12mediaBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory'; +import { clearCache } from '../../../libraries/boundingClientRect/boundingClientRect.js'; describe('H12 Media Adapter', function () { const DEFAULT_CURRENCY = 'USD'; @@ -88,8 +88,8 @@ describe('H12 Media Adapter', function () { } }, usersync: [ - {url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'image'}, - {url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'iframe'} + { url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'image' }, + { url: 'https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies={gdpr}&gdpr_consent_string={gdpr_cs}', type: 'iframe' } ], }; @@ -196,7 +196,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid, validBid2], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.include({adunitSize: validBid.mediaTypes.banner.sizes}); + expect(requestsData).to.include({ adunitSize: validBid.mediaTypes.banner.sizes }); }); it('should return empty bid size', function () { @@ -205,7 +205,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid, validBid2], bidderRequest); const requestsData2 = requests[1].data.bidrequest; - expect(requestsData2).to.deep.include({adunitSize: []}); + expect(requestsData2).to.deep.include({ adunitSize: [] }); }); it('should return pubsubid from params', function () { @@ -215,19 +215,19 @@ describe('H12 Media Adapter', function () { const requestsData = requests[0].data.bidrequest; const requestsData2 = requests[1].data.bidrequest; - expect(requestsData).to.include({pubsubid: 'pubsubtestid'}); - expect(requestsData2).to.include({pubsubid: ''}); + expect(requestsData).to.include({ pubsubid: 'pubsubtestid' }); + expect(requestsData2).to.include({ pubsubid: '' }); }); it('should return empty for incorrect pubsubid from params', function () { createElementVisible(validBid.adUnitCode); createElementVisible(validBid2.adUnitCode); - const bidWithPub = {...validBid}; + const bidWithPub = { ...validBid }; bidWithPub.params.pubsubid = 'iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii'; // More than 32 chars const requests = spec.buildRequests([bidWithPub], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.include({pubsubid: ''}); + expect(requestsData).to.include({ pubsubid: '' }); }); it('should return bid size from params', function () { @@ -237,8 +237,8 @@ describe('H12 Media Adapter', function () { const requestsData = requests[0].data.bidrequest; const requestsData2 = requests[1].data.bidrequest; - expect(requestsData).to.include({size: ''}); - expect(requestsData2).to.include({size: validBid2.params.size}); + expect(requestsData).to.include({ size: '' }); + expect(requestsData2).to.include({ size: validBid2.params.size }); }); it('should return GDPR info', function () { @@ -248,32 +248,32 @@ describe('H12 Media Adapter', function () { const requestsData = requests[0].data; const requestsData2 = requests[1].data; - expect(requestsData).to.include({gdpr: true, gdpr_cs: bidderRequest.gdprConsent.consentString}); - expect(requestsData2).to.include({gdpr: true, gdpr_cs: bidderRequest.gdprConsent.consentString}); + expect(requestsData).to.include({ gdpr: true, gdpr_cs: bidderRequest.gdprConsent.consentString }); + expect(requestsData2).to.include({ gdpr: true, gdpr_cs: bidderRequest.gdprConsent.consentString }); }); it('should not have error on empty GDPR', function () { createElementVisible(validBid.adUnitCode); createElementVisible(validBid2.adUnitCode); - const bidderRequestWithoutGDRP = {...bidderRequest, gdprConsent: null}; + const bidderRequestWithoutGDRP = { ...bidderRequest, gdprConsent: null }; const requests = spec.buildRequests([validBid, validBid2], bidderRequestWithoutGDRP); const requestsData = requests[0].data; const requestsData2 = requests[1].data; - expect(requestsData).to.include({gdpr: false}); - expect(requestsData2).to.include({gdpr: false}); + expect(requestsData).to.include({ gdpr: false }); + expect(requestsData2).to.include({ gdpr: false }); }); it('should not have error on empty USP', function () { createElementVisible(validBid.adUnitCode); createElementVisible(validBid2.adUnitCode); - const bidderRequestWithoutUSP = {...bidderRequest, uspConsent: null}; + const bidderRequestWithoutUSP = { ...bidderRequest, uspConsent: null }; const requests = spec.buildRequests([validBid, validBid2], bidderRequestWithoutUSP); const requestsData = requests[0].data; const requestsData2 = requests[1].data; - expect(requestsData).to.include({usp: false}); - expect(requestsData2).to.include({usp: false}); + expect(requestsData).to.include({ usp: false }); + expect(requestsData2).to.include({ usp: false }); }); it('should create single POST', function () { @@ -292,7 +292,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.deep.include({coords: {x: 10, y: 10}}); + expect(requestsData).to.deep.include({ coords: { x: 10, y: 10 } }); }); it('should define iframe', function () { @@ -302,8 +302,8 @@ describe('H12 Media Adapter', function () { const requestsData = requests[0].data; const requestsData2 = requests[1].data; - expect(requestsData).to.include({isiframe: true}); - expect(requestsData2).to.include({isiframe: true}); + expect(requestsData).to.include({ isiframe: true }); + expect(requestsData2).to.include({ isiframe: true }); }); it('should define visible element', function () { @@ -311,7 +311,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.include({ishidden: false}); + expect(requestsData).to.include({ ishidden: false }); }); it('should define invisible element', function () { @@ -319,7 +319,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.include({ishidden: true}); + expect(requestsData).to.include({ ishidden: true }); }); it('should define hidden element', function () { @@ -327,7 +327,7 @@ describe('H12 Media Adapter', function () { const requests = spec.buildRequests([validBid], bidderRequest); const requestsData = requests[0].data.bidrequest; - expect(requestsData).to.include({ishidden: true}); + expect(requestsData).to.include({ ishidden: true }); }); }); @@ -348,7 +348,7 @@ describe('H12 Media Adapter', function () { createElementVisible(validBid.adUnitCode); createElementVisible(validBid2.adUnitCode); const request = spec.buildRequests([validBid, validBid2], bidderRequest); - const bidResponse = spec.interpretResponse({body: serverResponse}, request[0]); + const bidResponse = spec.interpretResponse({ body: serverResponse }, request[0]); expect(bidResponse[0]).to.deep.include({ requestId: validBid.bidId, @@ -370,7 +370,7 @@ describe('H12 Media Adapter', function () { createElementVisible(validBid.adUnitCode); createElementVisible(validBid2.adUnitCode); const request = spec.buildRequests([validBid, validBid2], bidderRequest); - const bidResponse = spec.interpretResponse({body: serverResponse2}, request[0]); + const bidResponse = spec.interpretResponse({ body: serverResponse2 }, request[0]); expect(bidResponse[0]).to.deep.include({ requestId: validBid2.bidId, @@ -404,7 +404,7 @@ describe('H12 Media Adapter', function () { type: 'image', url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=${bidderRequest.gdprConsent.gdprApplies}&gdpr_consent_string=${bidderRequest.gdprConsent.consentString}`, }; - const syncs = spec.getUserSyncs(syncOptions, [{body: serverResponse}], bidderRequest.gdprConsent); + const syncs = spec.getUserSyncs(syncOptions, [{ body: serverResponse }], bidderRequest.gdprConsent); expect(syncs).to.deep.include(result); }); @@ -414,7 +414,7 @@ describe('H12 Media Adapter', function () { type: 'iframe', url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=${bidderRequest.gdprConsent.gdprApplies}&gdpr_consent_string=${bidderRequest.gdprConsent.consentString}`, }; - const syncs = spec.getUserSyncs(syncOptions, [{body: serverResponse}], bidderRequest.gdprConsent); + const syncs = spec.getUserSyncs(syncOptions, [{ body: serverResponse }], bidderRequest.gdprConsent); expect(syncs).to.deep.include(result); }); @@ -425,15 +425,15 @@ describe('H12 Media Adapter', function () { url: `https://cookiesync.3rdpartypartner.com/?3rdparty_partner_user_id={user_id}&partner_id=h12media&gdpr_applies=false&gdpr_consent_string=`, }; - expect(spec.getUserSyncs(syncOptions, [{body: serverResponse}], null)).to.deep.include(result); + expect(spec.getUserSyncs(syncOptions, [{ body: serverResponse }], null)).to.deep.include(result); }); it('should success without usersync url', function () { - expect(spec.getUserSyncs(syncOptions, [{body: serverResponse2}], bidderRequest.gdprConsent)).to.deep.equal([]); + expect(spec.getUserSyncs(syncOptions, [{ body: serverResponse2 }], bidderRequest.gdprConsent)).to.deep.equal([]); }); it('should return empty usersync on empty response', function () { - expect(spec.getUserSyncs(syncOptions, [{body: {}}])).to.deep.equal([]); + expect(spec.getUserSyncs(syncOptions, [{ body: {} }])).to.deep.equal([]); }); }); }); diff --git a/test/spec/modules/hadronIdSystem_spec.js b/test/spec/modules/hadronIdSystem_spec.js index 70aaf06bcc8..be4ca7be8b5 100644 --- a/test/spec/modules/hadronIdSystem_spec.js +++ b/test/spec/modules/hadronIdSystem_spec.js @@ -1,8 +1,8 @@ -import {hadronIdSubmodule, storage, LS_TAM_KEY} from 'modules/hadronIdSystem.js'; -import {server} from 'test/mocks/xhr.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { hadronIdSubmodule, storage, LS_TAM_KEY } from 'modules/hadronIdSystem.js'; +import { server } from 'test/mocks/xhr.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; describe('HadronIdSystem', function () { const HADRON_TEST = 'tstCachedHadronId1'; @@ -23,7 +23,7 @@ describe('HadronIdSystem', function () { }; getDataFromLocalStorageStub.withArgs(LS_TAM_KEY).returns(HADRON_TEST); const result = hadronIdSubmodule.getId(config); - expect(result).to.deep.equal({id: HADRON_TEST}); + expect(result).to.deep.equal({ id: HADRON_TEST }); }); it('allows configurable id url', function () { diff --git a/test/spec/modules/hadronRtdProvider_spec.js b/test/spec/modules/hadronRtdProvider_spec.js index 8f535c37ce4..f15d30b0144 100644 --- a/test/spec/modules/hadronRtdProvider_spec.js +++ b/test/spec/modules/hadronRtdProvider_spec.js @@ -1,4 +1,4 @@ -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import { HADRONID_LOCAL_NAME, RTD_LOCAL_NAME, @@ -7,9 +7,9 @@ import { hadronSubmodule, storage } from 'modules/hadronRtdProvider.js'; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; -const responseHeader = {'Content-Type': 'application/json'}; +const responseHeader = { 'Content-Type': 'application/json' }; describe('hadronRtdProvider', function () { let getDataFromLocalStorageStub; @@ -35,7 +35,7 @@ describe('hadronRtdProvider', function () { const setConfigUserObj1 = { name: 'www.dataprovider1.com', - ext: {taxonomyname: 'iab_audience_taxonomy'}, + ext: { taxonomyname: 'iab_audience_taxonomy' }, segment: [{ id: '1776' }] @@ -43,7 +43,7 @@ describe('hadronRtdProvider', function () { const setConfigUserObj2 = { name: 'www.dataprovider2.com', - ext: {taxonomyname: 'iab_audience_taxonomy'}, + ext: { taxonomyname: 'iab_audience_taxonomy' }, segment: [{ id: '1914' }] @@ -135,7 +135,7 @@ describe('hadronRtdProvider', function () { const userObj1 = { name: 'www.dataprovider1.com', - ext: {taxonomyname: 'iab_audience_taxonomy'}, + ext: { taxonomyname: 'iab_audience_taxonomy' }, segment: [{ id: '1776' }] @@ -143,7 +143,7 @@ describe('hadronRtdProvider', function () { const userObj2 = { name: 'www.dataprovider2.com', - ext: {taxonomyname: 'iab_audience_taxonomy'}, + ext: { taxonomyname: 'iab_audience_taxonomy' }, segment: [{ id: '1914' }] @@ -207,7 +207,7 @@ describe('hadronRtdProvider', function () { const configUserObj1 = { name: 'www.dataprovider1.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '1776' }] @@ -215,7 +215,7 @@ describe('hadronRtdProvider', function () { const configUserObj2 = { name: 'www.dataprovider2.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '1914' }] @@ -223,7 +223,7 @@ describe('hadronRtdProvider', function () { const configUserObj3 = { name: 'www.dataprovider1.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '2003' }] @@ -384,7 +384,7 @@ describe('hadronRtdProvider', function () { const userObj1 = { name: 'www.dataprovider1.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '1776' }] @@ -392,7 +392,7 @@ describe('hadronRtdProvider', function () { const userObj2 = { name: 'www.dataprovider2.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '1914' }] @@ -400,7 +400,7 @@ describe('hadronRtdProvider', function () { const userObj3 = { name: 'www.dataprovider1.com', - ext: {segtax: 3}, + ext: { segtax: 3 }, segment: [{ id: '2003' }] @@ -513,9 +513,9 @@ describe('hadronRtdProvider', function () { params: { handleRtd: function (bidConfig, rtd, rtdConfig, pbConfig) { if (String(rtd.ortb2.user.data[0].segment[0].id) === '1776') { - pbConfig.setConfig({ortb2: rtd.ortb2}); + pbConfig.setConfig({ ortb2: rtd.ortb2 }); } else { - pbConfig.setConfig({ortb2: {}}); + pbConfig.setConfig({ ortb2: {} }); } } } @@ -525,7 +525,7 @@ describe('hadronRtdProvider', function () { const rtdUserObj1 = { name: 'www.dataprovider.com', - ext: {taxonomyname: 'iab_audience_taxonomy'}, + ext: { taxonomyname: 'iab_audience_taxonomy' }, segment: [{ id: '1776' }] @@ -621,8 +621,8 @@ describe('hadronRtdProvider', function () { }; const rtd = { - adBuzz: [{id: 'adBuzzSeg2'}, {id: 'adBuzzSeg3'}], - trueBid: [{id: 'truebidSeg1'}, {id: 'truebidSeg2'}, {id: 'truebidSeg3'}] + adBuzz: [{ id: 'adBuzzSeg2' }, { id: 'adBuzzSeg3' }], + trueBid: [{ id: 'truebidSeg1' }, { id: 'truebidSeg2' }, { id: 'truebidSeg3' }] }; addRealTimeData(bidConfig, rtd, rtdConfig); @@ -644,7 +644,7 @@ describe('hadronRtdProvider', function () { } }; - const bidConfig = {ortb2Fragments: {global: {}}}; + const bidConfig = { ortb2Fragments: { global: {} } }; const rtdUserObj1 = { name: 'www.dataprovider3.com', diff --git a/test/spec/modules/harionBidAdapter_spec.js b/test/spec/modules/harionBidAdapter_spec.js new file mode 100644 index 00000000000..d5a1dd509a6 --- /dev/null +++ b/test/spec/modules/harionBidAdapter_spec.js @@ -0,0 +1,475 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/harionBidAdapter.js'; +import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'Harion'; + +describe('HarionBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + + } + } + + const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, + refererInfo: { + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK', + } + }, + timeout: 500 + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and key parameters present', function () { + expect(spec.isBidRequestValid(bids[0])).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests(bids, bidderRequest); + + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + + it('Returns general data valid', function () { + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys( + 'deviceWidth', + 'deviceHeight', + 'device', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax', + 'bcat', + 'badv', + 'bapp', + 'battr' + ); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); + }); + + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + }) + }); + + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + const dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + const dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + const dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + const serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + const serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); +}); diff --git a/test/spec/modules/humansecurityRtdProvider_spec.js b/test/spec/modules/humansecurityRtdProvider_spec.js index c6ad163c544..2104ffc6edd 100644 --- a/test/spec/modules/humansecurityRtdProvider_spec.js +++ b/test/spec/modules/humansecurityRtdProvider_spec.js @@ -10,10 +10,7 @@ const { SUBMODULE_NAME, SCRIPT_URL, main, - load, - onImplLoaded, - onImplMessage, - onGetBidRequestData + load } = __TEST__; describe('humansecurity RTD module', function () { @@ -23,20 +20,20 @@ describe('humansecurity RTD module', function () { const sonarStubId = `sonar_${stubUuid}`; const stubWindow = { [sonarStubId]: undefined }; - beforeEach(function() { + beforeEach(function () { sandbox = sinon.createSandbox(); sandbox.stub(utils, 'getWindowSelf').returns(stubWindow); sandbox.stub(utils, 'generateUUID').returns(stubUuid); sandbox.stub(refererDetection, 'getRefererInfo').returns({ domain: 'example.com' }); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); describe('Initialization step', function () { let sandbox2; let connectSpy; - beforeEach(function() { + beforeEach(function () { sandbox2 = sinon.createSandbox(); connectSpy = sandbox.spy(); // Once the impl script is loaded, it registers the API using session ID @@ -46,6 +43,17 @@ describe('humansecurity RTD module', function () { sandbox2.restore(); }); + it('should connect to the implementation script once it loads', function () { + load({}); + + expect(loadExternalScriptStub.calledOnce).to.be.true; + const callback = loadExternalScriptStub.getCall(0).args[3]; + expect(callback).to.be.a('function'); + const args = connectSpy.getCall(0).args; + expect(args[0]).to.haveOwnProperty('cmd'); // pbjs global + expect(args[0]).to.haveOwnProperty('que'); + }); + it('should accept valid configurations', function () { // Default configuration - empty expect(() => load({})).to.not.throw(); @@ -62,14 +70,19 @@ describe('humansecurity RTD module', function () { }); it('should insert implementation script', () => { - load({ }); + load({}); expect(loadExternalScriptStub.calledOnce).to.be.true; const args = loadExternalScriptStub.getCall(0).args; - expect(args[0]).to.be.equal(`${SCRIPT_URL}?r=example.com`); + expect(args[0]).to.include(`${SCRIPT_URL}?r=example.com`); + const mvMatch = args[0].match(/[?&]mv=([^&]+)/); + expect(mvMatch).to.not.equal(null); + const mvValue = Number(mvMatch[1]); + expect(Number.isFinite(mvValue)).to.equal(true); + expect(mvValue).to.be.greaterThan(0); expect(args[2]).to.be.equal(SUBMODULE_NAME); - expect(args[3]).to.be.equal(onImplLoaded); + expect(args[3]).to.be.a('function'); expect(args[4]).to.be.equal(null); expect(args[5]).to.be.deep.equal({ 'data-sid': 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' }); }); @@ -80,90 +93,14 @@ describe('humansecurity RTD module', function () { expect(loadExternalScriptStub.calledOnce).to.be.true; const args = loadExternalScriptStub.getCall(0).args; - expect(args[0]).to.be.equal(`${SCRIPT_URL}?r=example.com&c=customer123`); - }); - - it('should connect to the implementation script once it loads', function () { - load({ }); - - expect(loadExternalScriptStub.calledOnce).to.be.true; - expect(connectSpy.calledOnce).to.be.true; - - const args = connectSpy.getCall(0).args; - expect(args[0]).to.haveOwnProperty('cmd'); // pbjs global - expect(args[0]).to.haveOwnProperty('que'); - expect(args[1]).to.be.equal(onImplMessage); - }); - }); - - describe('Bid enrichment step', function () { - const hmnsData = { 'v1': 'sometoken' }; - - let sandbox2; - let callbackSpy; - let reqBidsConfig; - beforeEach(function() { - sandbox2 = sinon.createSandbox(); - callbackSpy = sandbox2.spy(); - reqBidsConfig = { ortb2Fragments: { bidder: {}, global: {} } }; - }); - afterEach(function () { - sandbox2.restore(); - }); - - it('should add empty device.ext.hmns to global ortb2 when data is yet to be received from the impl script', () => { - load({ }); - - onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); - - expect(callbackSpy.calledOnce).to.be.true; - expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('device'); - expect(reqBidsConfig.ortb2Fragments.global.device).to.have.own.property('ext'); - expect(reqBidsConfig.ortb2Fragments.global.device.ext).to.have.own.property('hmns').which.is.an('object').that.deep.equals({}); - }); - - it('should add the default device.ext.hmns to global ortb2 when no "hmns" data was yet received', () => { - load({ }); - - onImplMessage({ type: 'info', data: 'not a hmns message' }); - onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); - - expect(callbackSpy.calledOnce).to.be.true; - expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('device'); - expect(reqBidsConfig.ortb2Fragments.global.device).to.have.own.property('ext'); - expect(reqBidsConfig.ortb2Fragments.global.device.ext).to.have.own.property('hmns').which.is.an('object').that.deep.equals({}); - }); - - it('should add device.ext.hmns with received tokens to global ortb2 when the data was received', () => { - load({ }); - - onImplMessage({ type: 'hmns', data: hmnsData }); - onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); - - expect(callbackSpy.calledOnce).to.be.true; - expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('device'); - expect(reqBidsConfig.ortb2Fragments.global.device).to.have.own.property('ext'); - expect(reqBidsConfig.ortb2Fragments.global.device.ext).to.have.own.property('hmns').which.is.an('object').that.deep.equals(hmnsData); - }); - - it('should update device.ext.hmns with new data', () => { - load({ }); - - onImplMessage({ type: 'hmns', data: { 'v1': 'should be overwritten' } }); - onImplMessage({ type: 'hmns', data: hmnsData }); - onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); - - expect(callbackSpy.calledOnce).to.be.true; - expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('device'); - expect(reqBidsConfig.ortb2Fragments.global.device).to.have.own.property('ext'); - expect(reqBidsConfig.ortb2Fragments.global.device.ext).to.have.own.property('hmns').which.is.an('object').that.deep.equals(hmnsData); + expect(args[0]).to.include(`${SCRIPT_URL}?r=example.com&c=customer123`); }); }); - describe('Sumbodule execution', function() { + describe('Submodule execution', function () { let sandbox2; let submoduleStub; - beforeEach(function() { + beforeEach(function () { sandbox2 = sinon.createSandbox(); submoduleStub = sandbox2.stub(hook, 'submodule'); }); @@ -203,7 +140,7 @@ describe('humansecurity RTD module', function () { it('should commence initialization on default initialization', function () { const { init } = getModule(); - expect(init({ })).to.equal(true); + expect(init({})).to.equal(true); expect(loadExternalScriptStub.calledOnce).to.be.true; }); }); diff --git a/test/spec/modules/hybridBidAdapter_spec.js b/test/spec/modules/hybridBidAdapter_spec.js index a0d479fb4dc..6a49ce1a54d 100644 --- a/test/spec/modules/hybridBidAdapter_spec.js +++ b/test/spec/modules/hybridBidAdapter_spec.js @@ -36,15 +36,15 @@ describe('Hybrid.ai Adapter', function() { } const validBidRequests = [ getSlotConfigs({ banner: {} }, bannerMandatoryParams), - getSlotConfigs({ video: {playerSize: [[640, 480]], context: 'outstream'} }, videoMandatoryParams), - getSlotConfigs({ banner: {sizes: [0, 0]} }, inImageMandatoryParams) + getSlotConfigs({ video: { playerSize: [[640, 480]], context: 'outstream' } }, videoMandatoryParams), + getSlotConfigs({ banner: { sizes: [0, 0] } }, inImageMandatoryParams) ] describe('isBidRequestValid method', function() { describe('returns true', function() { describe('when banner slot config has all mandatory params', () => { describe('and banner placement has the correct value', function() { const slotConfig = getSlotConfigs( - {banner: {}}, + { banner: {} }, { placeId: PLACE_ID, placement: 'banner' diff --git a/test/spec/modules/hypelabBidAdapter_spec.js b/test/spec/modules/hypelabBidAdapter_spec.js index ff98c33b136..a8cb6abee6f 100644 --- a/test/spec/modules/hypelabBidAdapter_spec.js +++ b/test/spec/modules/hypelabBidAdapter_spec.js @@ -13,7 +13,7 @@ import { } from 'modules/hypelabBidAdapter.js'; import { BANNER } from 'src/mediaTypes.js'; -import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; +import { getDevicePixelRatio } from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; const mockValidBidRequest = { bidder: 'hypelab', diff --git a/test/spec/modules/id5AnalyticsAdapter_spec.js b/test/spec/modules/id5AnalyticsAdapter_spec.js index 1e1df900f81..7073e1e9ac0 100644 --- a/test/spec/modules/id5AnalyticsAdapter_spec.js +++ b/test/spec/modules/id5AnalyticsAdapter_spec.js @@ -1,12 +1,12 @@ import adapterManager from '../../../src/adapterManager.js'; import id5AnalyticsAdapter from '../../../modules/id5AnalyticsAdapter.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; import * as events from '../../../src/events.js'; -import {EVENTS} from '../../../src/constants.js'; -import {generateUUID} from '../../../src/utils.js'; -import {server} from '../../mocks/xhr.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; -import {enrichEidsRule} from "../../../modules/tcfControl.ts"; +import { EVENTS } from '../../../src/constants.js'; +import { generateUUID } from '../../../src/utils.js'; +import { server } from '../../mocks/xhr.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; +import { enrichEidsRule } from "../../../modules/tcfControl.ts"; import * as utils from '../../../src/utils.js'; const CONFIG_URL = 'https://api.id5-sync.com/analytics/12349/pbjs'; @@ -188,7 +188,7 @@ describe('ID5 analytics adapter', () => { 'criteoId': '_h_y_19IMUhMZG1TOTRReHFNc29TekJ3TzQ3elhnRU81ayUyQjhiRkdJJTJGaTFXJTJCdDRnVmN4S0FETUhQbXdmQWg0M3g1NWtGbGolMkZXalclMkJvWjJDOXFDSk1HU3ZKaVElM0QlM0Q', 'id5id': { 'uid': 'ID5-ZHMOQ99ulpk687Fd9xVwzxMsYtkQIJnI-qm3iWdtww!ID5*FSycZQy7v7zWXiKbEpPEWoB3_UiWdPGzh554ncYDvOkAAA3rajiR0yNrFAU7oDTu', - 'ext': {'linkType': 1} + 'ext': { 'linkType': 1 } }, 'tdid': '888a6042-8f99-483b-aa26-23c44bc9166b' }, @@ -203,7 +203,7 @@ describe('ID5 analytics adapter', () => { 'uids': [{ 'id': 'ID5-ZHMOQ99ulpk687Fd9xVwzxMsYtkQIJnI-qm3iWdtww!ID5*FSycZQy7v7zWXiKbEpPEWoB3_UiWdPGzh554ncYDvOkAAA3rajiR0yNrFAU7oDTu', 'atype': 1, - 'ext': {'linkType': 1} + 'ext': { 'linkType': 1 } }] }] }]; @@ -517,7 +517,7 @@ describe('ID5 analytics adapter', () => { 'userId': { 'id5id': { 'uid': 'ID5-ZHMOQ99ulpk687Fd9xVwzxMsYtkQIJnI-qm3iWdtww!ID5*FSycZQy7v7zWXiKbEpPEWoB3_UiWdPGzh554ncYDvOkAAA3rajiR0yNrFAU7oDTu', - 'ext': {'linkType': 1} + 'ext': { 'linkType': 1 } } } }]; diff --git a/test/spec/modules/id5IdSystem_spec.js b/test/spec/modules/id5IdSystem_spec.js index 7249560c8c9..47b7623ae00 100644 --- a/test/spec/modules/id5IdSystem_spec.js +++ b/test/spec/modules/id5IdSystem_spec.js @@ -7,18 +7,18 @@ import { setSubmoduleRegistry, startAuctionHook } from '../../../modules/userId/index.ts'; -import {config} from '../../../src/config.js'; +import { config } from '../../../src/config.js'; import * as events from '../../../src/events.js'; -import {EVENTS} from '../../../src/constants.js'; +import { EVENTS } from '../../../src/constants.js'; import * as utils from '../../../src/utils.js'; -import {deepClone} from '../../../src/utils.js'; +import { deepClone } from '../../../src/utils.js'; import '../../../src/prebid.js'; -import {hook} from '../../../src/hook.js'; -import {mockGdprConsent} from '../../helpers/consentData.js'; -import {server} from '../../mocks/xhr.js'; -import {expect} from 'chai'; -import {PbPromise} from '../../../src/utils/promise.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { hook } from '../../../src/hook.js'; +import { mockGdprConsent } from '../../helpers/consentData.js'; +import { server } from '../../mocks/xhr.js'; +import { expect } from 'chai'; +import { PbPromise } from '../../../src/utils/promise.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; describe('ID5 ID System', function () { let logInfoStub; @@ -199,9 +199,9 @@ describe('ID5 ID System', function () { function getAdUnitMock(code = 'adUnit-code') { return { code, - mediaTypes: {banner: {}, native: {}}, + mediaTypes: { banner: {}, native: {} }, sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}] + bids: [{ bidder: 'sampleBidder', params: { placementId: 'banner-only-bidder' } }] }; } @@ -391,30 +391,30 @@ describe('ID5 ID System', function () { expect(id5System.id5IdSubmodule.getId({})).is.eq(undefined); // valid params, invalid id5System.storage - expect(id5System.id5IdSubmodule.getId({params: {partner: 123}})).to.be.eq(undefined); - expect(id5System.id5IdSubmodule.getId({params: {partner: 123}, storage: {}})).to.be.eq(undefined); - expect(id5System.id5IdSubmodule.getId({params: {partner: 123}, storage: {name: ''}})).to.be.eq(undefined); - expect(id5System.id5IdSubmodule.getId({params: {partner: 123}, storage: {type: ''}})).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ params: { partner: 123 } })).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ params: { partner: 123 }, storage: {} })).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ params: { partner: 123 }, storage: { name: '' } })).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ params: { partner: 123 }, storage: { type: '' } })).to.be.eq(undefined); // valid id5System.storage, invalid params - expect(id5System.id5IdSubmodule.getId({storage: {name: 'name', type: 'html5'}})).to.be.eq(undefined); - expect(id5System.id5IdSubmodule.getId({storage: {name: 'name', type: 'html5'}, params: {}})).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5' } })).to.be.eq(undefined); + expect(id5System.id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5' }, params: {} })).to.be.eq(undefined); expect(id5System.id5IdSubmodule.getId({ - storage: {name: 'name', type: 'html5'}, - params: {partner: 'abc'} + storage: { name: 'name', type: 'html5' }, + params: { partner: 'abc' } })).to.be.eq(undefined); }); it('should warn with non-recommended id5System.storage params', function () { const logWarnStub = sinon.stub(utils, 'logWarn'); - id5System.id5IdSubmodule.getId({storage: {name: 'name', type: 'html5'}, params: {partner: 123}}); + id5System.id5IdSubmodule.getId({ storage: { name: 'name', type: 'html5' }, params: { partner: 123 } }); expect(logWarnStub.calledOnce).to.be.true; logWarnStub.restore(); id5System.id5IdSubmodule.getId({ - storage: {name: id5System.ID5_STORAGE_NAME, type: 'cookie'}, - params: {partner: 123} + storage: { name: id5System.ID5_STORAGE_NAME, type: 'cookie' }, + params: { partner: 123 } }); expect(logWarnStub.calledOnce).to.be.true; logWarnStub.restore(); @@ -423,14 +423,14 @@ describe('ID5 ID System', function () { describe('Check for valid consent', function () { const dataConsentVals = [ - [{purpose: {consents: {1: false}}}, {vendor: {consents: {131: true}}}, ' no purpose consent'], - [{purpose: {consents: {1: true}}}, {vendor: {consents: {131: false}}}, ' no vendor consent'], - [{purpose: {consents: {1: false}}}, {vendor: {consents: {131: false}}}, ' no purpose and vendor consent'], - [{purpose: {consents: undefined}}, {vendor: {consents: {131: true}}}, ' undefined purpose consent'], - [{purpose: {consents: {1: false}}}, {vendor: {consents: undefined}}], ' undefined vendor consent', - [undefined, {vendor: {consents: {131: true}}}, ' undefined purpose'], - [{purpose: {consents: {1: true}}}, {vendor: undefined}, ' undefined vendor'], - [{purpose: {consents: {1: true}}}, {vendor: {consents: {31: true}}}, ' incorrect vendor consent'] + [{ purpose: { consents: { 1: false } } }, { vendor: { consents: { 131: true } } }, ' no purpose consent'], + [{ purpose: { consents: { 1: true } } }, { vendor: { consents: { 131: false } } }, ' no vendor consent'], + [{ purpose: { consents: { 1: false } } }, { vendor: { consents: { 131: false } } }, ' no purpose and vendor consent'], + [{ purpose: { consents: undefined } }, { vendor: { consents: { 131: true } } }, ' undefined purpose consent'], + [{ purpose: { consents: { 1: false } } }, { vendor: { consents: undefined } }], ' undefined vendor consent', + [undefined, { vendor: { consents: { 131: true } } }, ' undefined purpose'], + [{ purpose: { consents: { 1: true } } }, { vendor: undefined }, ' undefined vendor'], + [{ purpose: { consents: { 1: true } } }, { vendor: { consents: { 31: true } } }, ' incorrect vendor consent'] ]; dataConsentVals.forEach(function ([purposeConsent, vendorConsent, caseName]) { @@ -442,10 +442,10 @@ describe('ID5 ID System', function () { purposeConsent, vendorConsent } }; - expect(id5System.id5IdSubmodule.getId(config, {gdpr: dataConsent})).is.eq(undefined); + expect(id5System.id5IdSubmodule.getId(config, { gdpr: dataConsent })).is.eq(undefined); const cacheIdObject = 'cacheIdObject'; - expect(id5System.id5IdSubmodule.extendId(config, {gdpr: dataConsent}, cacheIdObject)).is.eql({id: cacheIdObject}); + expect(id5System.id5IdSubmodule.extendId(config, { gdpr: dataConsent }, cacheIdObject)).is.eql({ id: cacheIdObject }); }); }); }); @@ -501,7 +501,7 @@ describe('ID5 ID System', function () { // Trigger the fetch but we await on it later const config = getId5FetchConfig(); - const submoduleResponsePromise = callSubmoduleGetId(config, {gdpr: consentData}, undefined); + const submoduleResponsePromise = callSubmoduleGetId(config, { gdpr: consentData }, undefined); const fetchRequest = await xhrServerMock.expectFetchRequest(); const requestBody = JSON.parse(fetchRequest.requestBody); @@ -548,7 +548,7 @@ describe('ID5 ID System', function () { // Trigger the fetch but we await on it later const config = getId5FetchConfig(); - const submoduleResponsePromise = callSubmoduleGetId(config, {gdpr: consentData, usp: usPrivacyString}, undefined); + const submoduleResponsePromise = callSubmoduleGetId(config, { gdpr: consentData, usp: usPrivacyString }, undefined); const fetchRequest = await xhrServerMock.expectFetchRequest(); const requestBody = JSON.parse(fetchRequest.requestBody); @@ -859,7 +859,7 @@ describe('ID5 ID System', function () { it('should call the ID5 server with ab_testing object when abTesting is turned on', async function () { const xhrServerMock = new XhrServerMock(server); const id5Config = getId5FetchConfig(); - id5Config.params.abTesting = {enabled: true, controlGroupPct: 0.234}; + id5Config.params.abTesting = { enabled: true, controlGroupPct: 0.234 }; // Trigger the fetch but we await on it later const submoduleResponsePromise = callSubmoduleGetId(id5Config, undefined, oldStoredObject(ID5_STORED_OBJ)); @@ -876,7 +876,7 @@ describe('ID5 ID System', function () { it('should call the ID5 server without ab_testing object when abTesting is turned off', async function () { const xhrServerMock = new XhrServerMock(server); const id5Config = getId5FetchConfig(); - id5Config.params.abTesting = {enabled: false, controlGroupPct: 0.55}; + id5Config.params.abTesting = { enabled: false, controlGroupPct: 0.55 }; // Trigger the fetch but we await on it later const submoduleResponsePromise = callSubmoduleGetId(id5Config, undefined, oldStoredObject(ID5_STORED_OBJ)); @@ -969,7 +969,7 @@ describe('ID5 ID System', function () { gppString: 'GPP_STRING', applicableSections: [2] }; - const submoduleResponse = callSubmoduleGetId(getId5FetchConfig(), {gpp: gppData}, oldStoredObject(ID5_STORED_OBJ)); + const submoduleResponse = callSubmoduleGetId(getId5FetchConfig(), { gpp: gppData }, oldStoredObject(ID5_STORED_OBJ)); return xhrServerMock.expectFetchRequest() .then(fetchRequest => { @@ -1003,7 +1003,7 @@ describe('ID5 ID System', function () { return xhrServerMock.expectFetchRequest() .then(fetchRequest => { const requestBody = JSON.parse(fetchRequest.requestBody); - expect(requestBody.true_link).is.eql({booted: false}); + expect(requestBody.true_link).is.eql({ booted: false }); fetchRequest.respond(200, responseHeader, JSON.stringify(ID5_JSON_RESPONSE)); return submoduleResponse; }); @@ -1011,7 +1011,7 @@ describe('ID5 ID System', function () { it('should pass full true link info to ID5 server when true link is booted', function () { const xhrServerMock = new XhrServerMock(server); - const trueLinkResponse = {booted: true, redirected: true, id: 'TRUE_LINK_ID'}; + const trueLinkResponse = { booted: true, redirected: true, id: 'TRUE_LINK_ID' }; window.id5Bootstrap = { getTrueLinkInfo: function () { return trueLinkResponse; @@ -1105,7 +1105,7 @@ describe('ID5 ID System', function () { }] }); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); it('should add stored EUID from cache to bids', function (done) { @@ -1128,7 +1128,7 @@ describe('ID5 ID System', function () { }] }); done(); - }, {ortb2Fragments}); + }, { ortb2Fragments }); }); it('should add stored TRUE_LINK_ID from cache to bids', function (done) { @@ -1147,7 +1147,7 @@ describe('ID5 ID System', function () { }] }); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); }); @@ -1168,7 +1168,7 @@ describe('ID5 ID System', function () { return new Promise((resolve) => { startAuctionHook(() => { resolve(); - }, {adUnits}); + }, { adUnits }); }).then(() => { expect(xhrServerMock.hasReceivedAnyRequest()).is.false; events.emit(EVENTS.AUCTION_END, {}); @@ -1201,7 +1201,7 @@ describe('ID5 ID System', function () { }] }); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); it('should add stored EUID from cache to bids - from ids', function (done) { @@ -1222,7 +1222,7 @@ describe('ID5 ID System', function () { expect(eids[0]).is.eql(IDS_ID5ID.eid); expect(eids[1]).is.eql(IDS_EUID.eid); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); it('should add stored TRUE_LINK_ID from cache to bids - from ids', function (done) { @@ -1241,7 +1241,7 @@ describe('ID5 ID System', function () { startAuctionHook(wrapAsyncExpects(done, function () { expect(ortb2Fragments.global.user.ext.eids[1]).is.eql(IDS_TRUE_LINK_ID.eid); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); it('should add other id from cache to bids', function (done) { @@ -1286,13 +1286,13 @@ describe('ID5 ID System', function () { }] }); done(); - }), {ortb2Fragments}); + }), { ortb2Fragments }); }); }); }); describe('Decode id5response', function () { - const expectedDecodedObject = {id5id: {uid: ID5_STORED_ID, ext: {linkType: ID5_STORED_LINK_TYPE}}}; + const expectedDecodedObject = { id5id: { uid: ID5_STORED_ID, ext: { linkType: ID5_STORED_LINK_TYPE } } }; it('should return undefined if passed a string', function () { expect(id5System.id5IdSubmodule.decode('somestring', getId5FetchConfig())).is.eq(undefined); @@ -1315,7 +1315,7 @@ describe('ID5 ID System', function () { expect(id5System.id5IdSubmodule.decode(responseF(ID5_STORED_OBJ_WITH_EUID, config), config).euid).is.eql({ 'source': EUID_SOURCE, 'uid': EUID_STORED_ID, - 'ext': {'provider': ID5_SOURCE} + 'ext': { 'provider': ID5_SOURCE } }); }); it('should decode trueLinkId from a stored object with trueLinkId', function () { @@ -1361,13 +1361,8 @@ describe('ID5 ID System', function () { setTargetingStub = sinon.stub(); window.googletag = { cmd: [], - pubads: function () { - return { - setTargeting: setTargetingStub - }; - } + setConfig: setTargetingStub }; - sinon.spy(window.googletag, 'pubads'); storedObject = utils.deepClone(ID5_STORED_OBJ); }); @@ -1391,14 +1386,16 @@ describe('ID5 ID System', function () { for (const [tagName, tagValue] of Object.entries(tagsObj)) { const fullTagName = `${targetingEnabledConfig.params.gamTargetingPrefix}_${tagName}`; - const matchingCall = setTargetingStub.getCalls().find(call => call.args[0] === fullTagName); + const matchingCall = setTargetingStub.getCalls().find(call => { + const config = call.args[0]; + return config.targeting && config.targeting[fullTagName] !== undefined; + }); expect(matchingCall, `Tag ${fullTagName} was not set`).to.exist; - expect(matchingCall.args[1]).to.equal(tagValue); + expect(matchingCall.args[0].targeting[fullTagName]).to.equal(tagValue); } window.googletag.cmd = []; setTargetingStub.reset(); - window.googletag.pubads.resetHistory(); } it('should not set GAM targeting if it is not enabled', function () { @@ -1435,15 +1432,315 @@ describe('ID5 ID System', function () { }) }) + describe('Decode should also expose targeting via id5tags if configured', function () { + let origId5tags, storedObject; + const exposeTargetingConfig = getId5FetchConfig(); + exposeTargetingConfig.params.gamTargetingPrefix = 'id5'; + exposeTargetingConfig.params.exposeTargeting = true; + + beforeEach(function () { + delete window.id5tags; + storedObject = utils.deepClone(ID5_STORED_OBJ); + }); + + afterEach(function () { + delete window.id5tags; + id5System.id5IdSubmodule._reset(); + }); + + it('should not expose targeting if exposeTargeting is not enabled', function () { + const config = getId5FetchConfig(); + config.params.gamTargetingPrefix = 'id5'; + // exposeTargeting is not set + const testObj = { + ...storedObject, + 'tags': { + 'id': 'y', + 'ab': 'n' + } + }; + id5System.id5IdSubmodule.decode(testObj, config); + expect(window.id5tags).to.be.undefined; + }); + + it('should not expose targeting if tags not returned from server', function () { + // tags is not in the response + id5System.id5IdSubmodule.decode(storedObject, exposeTargetingConfig); + expect(window.id5tags).to.be.undefined; + }); + + it('should create id5tags.cmd when it does not exist pre-decode', function () { + const testObj = { + ...storedObject, + 'tags': { + 'id': 'y', + 'ab': 'n' + } + }; + id5System.id5IdSubmodule.decode(testObj, exposeTargetingConfig); + + expect(window.id5tags).to.exist; + expect(window.id5tags.cmd).to.be.an('array'); + expect(window.id5tags.tags).to.deep.equal({ + 'id': 'y', + 'ab': 'n' + }); + }); + + it('should execute queued functions when cmd was created earlier', async function () { + const testTags = { + 'id': 'y', + 'ab': 'n', + 'enrich': 'y' + }; + const testObj = { + ...storedObject, + 'tags': testTags + }; + + const callTracker = []; + let resolvePromise; + const callbackPromise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + // Pre-create id5tags with queued functions + window.id5tags = { + cmd: [ + (tags) => callTracker.push({ call: 1, tags: tags }), + (tags) => callTracker.push({ call: 2, tags: tags }), + (tags) => { + callTracker.push({ call: 3, tags: tags }); + resolvePromise(); + } + ] + }; + + id5System.id5IdSubmodule.decode(testObj, exposeTargetingConfig); + + await callbackPromise; + + // Verify all queued functions were called with the tags + expect(callTracker).to.have.lengthOf(3); + expect(callTracker[0]).to.deep.equal({ call: 1, tags: testTags }); + expect(callTracker[1]).to.deep.equal({ call: 2, tags: testTags }); + expect(callTracker[2]).to.deep.equal({ call: 3, tags: testTags }); + + // Verify tags were stored + expect(window.id5tags.tags).to.deep.equal(testTags); + }); + + it('should override push method to execute functions immediately', function () { + const testTags = { + 'id': 'y', + 'ab': 'n' + }; + const testObj = { + ...storedObject, + 'tags': testTags + }; + + id5System.id5IdSubmodule.decode(testObj, exposeTargetingConfig); + + // Now push a new function and verify it executes immediately + let callResult = null; + window.id5tags.cmd.push((tags) => { + callResult = { executed: true, tags: tags }; + }); + + expect(callResult).to.not.be.null; + expect(callResult.executed).to.be.true; + expect(callResult.tags).to.deep.equal(testTags); + }); + + it('should retrigger functions when tags are different but not when tags are the same', async function () { + const firstTags = { + 'id': 'y', + 'ab': 'n' + }; + const secondTags = { + 'id': 'y', + 'ab': 'y', + 'enrich': 'y' + }; + + const firstObj = { + ...storedObject, + 'tags': firstTags + }; + + const callTracker = []; + + // First decode + let resolveFirstPromise; + const firstCallbackPromise = new Promise((resolve) => { + resolveFirstPromise = resolve; + }); + + window.id5tags = { + cmd: [ + (tags) => { + callTracker.push({ call: 'decode', tags: utils.deepClone(tags) }); + resolveFirstPromise(); + } + ] + }; + + id5System.id5IdSubmodule.decode(firstObj, exposeTargetingConfig); + + await firstCallbackPromise; + + expect(callTracker).to.have.lengthOf(1); + expect(callTracker[0].tags).to.deep.equal(firstTags); + + // Second decode with different tags - should retrigger + const secondObj = { + ...storedObject, + 'tags': secondTags + }; + + let resolveSecondPromise; + const secondCallbackPromise = new Promise((resolve) => { + resolveSecondPromise = resolve; + }); + + // Update the callback to resolve when called again + window.id5tags.cmd[0] = (tags) => { + callTracker.push({ call: 'decode', tags: utils.deepClone(tags) }); + resolveSecondPromise(); + }; + + id5System.id5IdSubmodule.decode(secondObj, exposeTargetingConfig); + + await secondCallbackPromise; + + // The queued function should be called again with new tags + expect(callTracker).to.have.lengthOf(2); + expect(callTracker[1].tags).to.deep.equal(secondTags); + expect(window.id5tags.tags).to.deep.equal(secondTags); + + // Third decode with identical tags content (but different object reference) - should NOT retrigger + const thirdObj = { + ...storedObject, + 'tags': { + 'id': 'y', + 'ab': 'y', + 'enrich': 'y' + } + }; + + id5System.id5IdSubmodule.decode(thirdObj, exposeTargetingConfig); + + // Give it a small delay to ensure it doesn't retrigger + await new Promise(resolve => setTimeout(resolve, 50)); + + // With deepEqual, this should NOT retrigger since content is the same as secondTags + expect(callTracker).to.have.lengthOf(2); + expect(window.id5tags.tags).to.deep.equal(secondTags); + }); + + it('should handle when someone else has set id5tags.cmd earlier', async function () { + const testTags = { + 'id': 'y', + 'ab': 'n' + }; + const testObj = { + ...storedObject, + 'tags': testTags + }; + + const externalCallTracker = []; + let resolvePromise; + const callbackPromise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + // External script creates id5tags + window.id5tags = { + cmd: [], + externalData: 'some-external-value' + }; + + // Add external function + window.id5tags.cmd.push((tags) => { + externalCallTracker.push({ external: true, tags: tags }); + resolvePromise(); + }); + + id5System.id5IdSubmodule.decode(testObj, exposeTargetingConfig); + + await callbackPromise; + + // External function should be called + expect(externalCallTracker).to.have.lengthOf(1); + expect(externalCallTracker[0].external).to.be.true; + expect(externalCallTracker[0].tags).to.deep.equal(testTags); + + // External data should be preserved + expect(window.id5tags.externalData).to.equal('some-external-value'); + + // Tags should be set + expect(window.id5tags.tags).to.deep.equal(testTags); + }); + + it('should work with both gamTargetingPrefix and exposeTargeting enabled', async function () { + // Setup googletag + const origGoogletag = window.googletag; + window.googletag = { + cmd: [], + setConfig: sinon.stub() + }; + + const testTags = { + 'id': 'y', + 'ab': 'n' + }; + const testObj = { + ...storedObject, + 'tags': testTags + }; + + const callTracker = []; + let resolvePromise; + const callbackPromise = new Promise((resolve) => { + resolvePromise = resolve; + }); + + window.id5tags = { + cmd: [(tags) => { + callTracker.push(tags); + resolvePromise(); + }] + }; + + id5System.id5IdSubmodule.decode(testObj, exposeTargetingConfig); + + await callbackPromise; + + // Both mechanisms should work + expect(window.googletag.cmd.length).to.be.at.least(1); + expect(callTracker).to.have.lengthOf(1); + expect(callTracker[0]).to.deep.equal(testTags); + expect(window.id5tags.tags).to.deep.equal(testTags); + + // Restore + if (origGoogletag) { + window.googletag = origGoogletag; + } else { + delete window.googletag; + } + }); + }); + describe('A/B Testing', function () { - const expectedDecodedObjectWithIdAbOff = {id5id: {uid: ID5_STORED_ID, ext: {linkType: ID5_STORED_LINK_TYPE}}}; + const expectedDecodedObjectWithIdAbOff = { id5id: { uid: ID5_STORED_ID, ext: { linkType: ID5_STORED_LINK_TYPE } } }; const expectedDecodedObjectWithIdAbOn = { id5id: { uid: ID5_STORED_ID, - ext: {linkType: ID5_STORED_LINK_TYPE, abTestingControlGroup: false} + ext: { linkType: ID5_STORED_LINK_TYPE, abTestingControlGroup: false } } }; - const expectedDecodedObjectWithoutIdAbOn = {id5id: {uid: '', ext: {linkType: 0, abTestingControlGroup: true}}}; + const expectedDecodedObjectWithoutIdAbOn = { id5id: { uid: '', ext: { linkType: 0, abTestingControlGroup: true } } }; let testConfig, storedObject; beforeEach(function () { @@ -1480,13 +1777,13 @@ describe('ID5 ID System', function () { }); it('should set abTestingControlGroup to false when A/B testing is on but in normal group', function () { - storedObject.ab_testing = {result: 'normal'}; + storedObject.ab_testing = { result: 'normal' }; const decoded = id5System.id5IdSubmodule.decode(id5PrebidResponse(storedObject, testConfig), testConfig); expect(decoded).is.eql(expectedDecodedObjectWithIdAbOn); }); it('should not expose ID when everyone is in control group', function () { - storedObject.ab_testing = {result: 'control'}; + storedObject.ab_testing = { result: 'control' }; storedObject.universal_uid = ''; storedObject.ext = { 'linkType': 0 @@ -1496,7 +1793,7 @@ describe('ID5 ID System', function () { }); it('should log A/B testing errors', function () { - storedObject.ab_testing = {result: 'error'}; + storedObject.ab_testing = { result: 'error' }; const decoded = id5System.id5IdSubmodule.decode(id5PrebidResponse(storedObject, testConfig), testConfig); expect(decoded).is.eql(expectedDecodedObjectWithIdAbOff); sinon.assert.calledOnce(logErrorSpy); @@ -1518,7 +1815,7 @@ describe('ID5 ID System', function () { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'id5-sync.com', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); diff --git a/test/spec/modules/idImportLibrary_spec.js b/test/spec/modules/idImportLibrary_spec.js index 4604d7ea465..f440789c09b 100644 --- a/test/spec/modules/idImportLibrary_spec.js +++ b/test/spec/modules/idImportLibrary_spec.js @@ -1,13 +1,13 @@ -import {init} from 'modules/userId/index.js'; +import { init } from 'modules/userId/index.js'; import * as utils from 'src/utils.js'; import * as idImportlibrary from 'modules/idImportLibrary.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; -import {config} from 'src/config.js'; -import {hook} from '../../../src/hook.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; +import { config } from 'src/config.js'; +import { hook } from '../../../src/hook.js'; import * as activities from '../../../src/activities/rules.js'; import { ACTIVITY_ENRICH_UFPD } from '../../../src/activities/activities.js'; import { CONF_DEFAULT_FULL_BODY_SCAN, CONF_DEFAULT_INPUT_SCAN } from '../../../modules/idImportLibrary.js'; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; var expect = require('chai').expect; @@ -110,7 +110,7 @@ describe('IdImportLibrary Tests', function () { refreshUserIdSpy = sinon.stub(getGlobal(), 'refreshUserIds'); clock = sinon.useFakeTimers(1046952000000); // 2003-03-06T12:00:00Z mutationObserverStub = sinon.stub(window, 'MutationObserver').returns(mockMutationObserver); - userId = sandbox.stub(getGlobal(), 'getUserIds').returns({id: {'MOCKID': '1111'}}); + userId = sandbox.stub(getGlobal(), 'getUserIds').returns({ id: { 'MOCKID': '1111' } }); server.respondWith('POST', 'URL', [200, { 'Content-Type': 'application/json', diff --git a/test/spec/modules/identityLinkIdSystem_spec.js b/test/spec/modules/identityLinkIdSystem_spec.js index fddca301e36..da3dbea10dc 100644 --- a/test/spec/modules/identityLinkIdSystem_spec.js +++ b/test/spec/modules/identityLinkIdSystem_spec.js @@ -1,17 +1,17 @@ -import {getEnvelopeFromStorage, identityLinkSubmodule} from 'modules/identityLinkIdSystem.js'; +import { getEnvelopeFromStorage, identityLinkSubmodule } from 'modules/identityLinkIdSystem.js'; import * as utils from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; -import {getCoreStorageManager} from '../../../src/storageManager.js'; -import {stub} from 'sinon'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { server } from 'test/mocks/xhr.js'; +import { getCoreStorageManager } from '../../../src/storageManager.js'; +import { stub } from 'sinon'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; const storage = getCoreStorageManager(); const pid = '14'; let defaultConfigParams; -const responseHeader = {'Content-Type': 'application/json'}; +const responseHeader = { 'Content-Type': 'application/json' }; const testEnvelope = 'eyJ0aW1lc3RhbXAiOjE2OTEwNjU5MzQwMTcsInZlcnNpb24iOiIxLjIuMSIsImVudmVsb3BlIjoiQWhIenUyMFN3WHZ6T0hPd3c2bkxaODAtd2hoN2Nnd0FqWllNdkQ0UjBXT25xRVc1N21zR2Vral9QejU2b1FwcGdPOVB2aFJFa3VHc2lMdG56c3A2aG13eDRtTTRNLTctRy12NiJ9'; const testEnvelopeValue = '{"timestamp":1691065934017,"version":"1.2.1","envelope":"AhHzu20SwXvzOHOww6nLZ80-whh7cgwAjZYMvD4R0WOnqEW57msGekj_Pz56oQppgO9PvhREkuGsiLtnzsp6hmwx4mM4M-7-G-v6"}'; @@ -26,7 +26,7 @@ describe('IdentityLinkId tests', function () { let gppConsentDataStub; beforeEach(function () { - defaultConfigParams = { params: {pid: pid} }; + defaultConfigParams = { params: { pid: pid } }; logErrorStub = sinon.stub(utils, 'logError'); // remove _lr_retry_request cookie before test storage.setCookie('_lr_retry_request', 'true', 'Thu, 01 Jan 1970 00:00:01 GMT'); @@ -68,13 +68,13 @@ describe('IdentityLinkId tests', function () { gdprApplies: true, consentString: '' }; - const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, {gdpr: consentData}); + const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, { gdpr: consentData }); expect(submoduleCallback).to.be.undefined; }); it('should NOT call the LiveRamp envelope endpoint if gdpr applies but consent string is missing', function () { const consentData = { gdprApplies: true }; - const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, {gdpr: consentData}); + const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, { gdpr: consentData }); expect(submoduleCallback).to.be.undefined; }); @@ -87,7 +87,7 @@ describe('IdentityLinkId tests', function () { tcfPolicyVersion: 2 } }; - const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, {gdpr: consentData}).callback; + const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, { gdpr: consentData }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14&ct=4&cv=CO4VThZO4VTiuADABBENAzCgAP_AAEOAAAAAAwwAgAEABhAAgAgAAA.YAAAAAAAAAA'); @@ -106,7 +106,7 @@ describe('IdentityLinkId tests', function () { applicableSections: [7] }; const callBackSpy = sinon.spy(); - const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, {gpp: gppData}).callback; + const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, { gpp: gppData }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14&gpp=DBABLA~BVVqAAAACqA.QA&gpp_sid=7'); @@ -125,7 +125,7 @@ describe('IdentityLinkId tests', function () { applicableSections: [7] }; const callBackSpy = sinon.spy(); - const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, {gpp: gppData}).callback; + const submoduleCallback = identityLinkSubmodule.getId(defaultConfigParams, { gpp: gppData }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq('https://api.rlcdn.com/api/identity/envelope?pid=14'); @@ -239,8 +239,10 @@ describe('IdentityLinkId tests', function () { it('if ats is present on a page, and envelope is generated and stored in storage, call a callback', function () { setTestEnvelopeCookie(); const envelopeValueFromStorage = getEnvelopeFromStorage(); - window.ats = {retrieveEnvelope: function() { - }} + window.ats = { + retrieveEnvelope: function() { + } + } // mock ats.retrieveEnvelope to return envelope stub(window.ats, 'retrieveEnvelope').callsFake(function() { return envelopeValueFromStorage }) const callBackSpy = sinon.spy(); @@ -262,7 +264,7 @@ describe('IdentityLinkId tests', function () { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'liveramp.com', - uids: [{id: 'some-random-id-value', atype: 3}] + uids: [{ id: 'some-random-id-value', atype: 3 }] }); }); }) diff --git a/test/spec/modules/idxIdSystem_spec.js b/test/spec/modules/idxIdSystem_spec.js index a5bb7d5d762..945cc4b263e 100644 --- a/test/spec/modules/idxIdSystem_spec.js +++ b/test/spec/modules/idxIdSystem_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {idxIdSubmodule, storage} from 'modules/idxIdSystem.js'; +import { expect } from 'chai'; +import { idxIdSubmodule, storage } from 'modules/idxIdSystem.js'; import 'src/prebid.js'; const IDX_COOKIE_NAME = '_idx'; diff --git a/test/spec/modules/illuminBidAdapter_spec.js b/test/spec/modules/illuminBidAdapter_spec.js index 05b803d5f82..50ccd555a4a 100644 --- a/test/spec/modules/illuminBidAdapter_spec.js +++ b/test/spec/modules/illuminBidAdapter_spec.js @@ -1,14 +1,14 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, storage } from 'modules/illuminBidAdapter.js'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; import { hashCode, extractPID, @@ -19,7 +19,7 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -103,9 +103,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -122,7 +122,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -193,9 +193,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -208,7 +207,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -330,9 +329,9 @@ describe('IlluminBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -404,9 +403,9 @@ describe('IlluminBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -451,7 +450,7 @@ describe('IlluminBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -460,7 +459,7 @@ describe('IlluminBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.illumin.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -468,7 +467,7 @@ describe('IlluminBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.illumin.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -480,7 +479,7 @@ describe('IlluminBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.illumin.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -495,12 +494,12 @@ describe('IlluminBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -573,9 +572,9 @@ describe('IlluminBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -596,7 +595,7 @@ describe('IlluminBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -607,11 +606,11 @@ describe('IlluminBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -626,7 +625,7 @@ describe('IlluminBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -641,11 +640,11 @@ describe('IlluminBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -658,18 +657,18 @@ describe('IlluminBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cId': '1'}); - const pid = extractPID({'pId': '2'}); - const subDomain = extractSubDomain({'subDomain': 'prebid'}); + const cid = extractCID({ 'cId': '1' }); + const pid = extractPID({ 'pId': '2' }); + const subDomain = extractSubDomain({ 'subDomain': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -729,7 +728,7 @@ describe('IlluminBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -745,8 +744,8 @@ describe('IlluminBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/imRtdProvider_spec.js b/test/spec/modules/imRtdProvider_spec.js index b06afc5a85b..511beedc15d 100644 --- a/test/spec/modules/imRtdProvider_spec.js +++ b/test/spec/modules/imRtdProvider_spec.js @@ -60,12 +60,12 @@ describe('imRtdProvider', function () { }); it(`should return bid with correct key data: ${bidderName}`, function () { - const bid = {bidder: bidderName}; - expect(getBidderFunction(bidderName)(bid, {'im_segments': ['12345', '67890']}, {params: {}})).to.equal(bid); + const bid = { bidder: bidderName }; + expect(getBidderFunction(bidderName)(bid, { 'im_segments': ['12345', '67890'] }, { params: {} })).to.equal(bid); }); it(`should return bid without data: ${bidderName}`, function () { - const bid = {bidder: bidderName}; - expect(getBidderFunction(bidderName)(bid, '', {params: {}})).to.equal(bid); + const bid = { bidder: bidderName }; + expect(getBidderFunction(bidderName)(bid, '', { params: {} })).to.equal(bid); }); }); it(`should return null with unexpected bidder`, function () { @@ -73,8 +73,8 @@ describe('imRtdProvider', function () { }); describe('fluct bidder function', function () { it('should return a bid w/o im_segments if not any exists', function () { - const bid = {bidder: 'fluct'}; - expect(getBidderFunction('fluct')(bid, '', {params: {}})).to.eql(bid); + const bid = { bidder: 'fluct' }; + expect(getBidderFunction('fluct')(bid, '', { params: {} })).to.eql(bid); }); it('should return a bid w/ im_segments if any exists', function () { const bid = { @@ -87,8 +87,8 @@ describe('imRtdProvider', function () { }; expect(getBidderFunction('fluct')( bid, - {im_segments: ['12345', '67890', '09876']}, - {params: {maxSegments: 2}} + { im_segments: ['12345', '67890', '09876'] }, + { params: { maxSegments: 2 } } )) .to.eql( { @@ -139,7 +139,7 @@ describe('imRtdProvider', function () { describe('setRealTimeData', function () { it('should return true when empty params', function () { - expect(setRealTimeData({adUnits: []}, {params: {}}, {im_segments: []})).to.equal(undefined) + expect(setRealTimeData({ adUnits: [] }, { params: {} }, { im_segments: [] })).to.equal(undefined) }); it('should return true when overwrites and bid params', function () { const config = { @@ -149,7 +149,7 @@ describe('imRtdProvider', function () { } } }; - expect(setRealTimeData(testReqBidsConfigObj, config, {im_segments: []})).to.equal(undefined) + expect(setRealTimeData(testReqBidsConfigObj, config, { im_segments: [] })).to.equal(undefined) }); }) @@ -197,13 +197,13 @@ describe('imRtdProvider', function () { it('should return "undefined" success', function () { const res = getApiCallback(testReqBidsConfigObj, false, moduleConfig); const successResponse = '{"uid": "testid", "segments": "testsegment", "vid": "testvid"}'; - expect(res.success(successResponse, {status: 200})).to.equal(undefined); + expect(res.success(successResponse, { status: 200 })).to.equal(undefined); expect(res.error()).to.equal(undefined); }); it('should return "undefined" catch error response', function () { const res = getApiCallback(testReqBidsConfigObj, false, moduleConfig); - expect(res.success('error response', {status: 400})).to.equal(undefined); + expect(res.success('error response', { status: 400 })).to.equal(undefined); }); }) }) diff --git a/test/spec/modules/impactifyBidAdapter_spec.js b/test/spec/modules/impactifyBidAdapter_spec.js index 464bf4f5972..641a58ae9d8 100644 --- a/test/spec/modules/impactifyBidAdapter_spec.js +++ b/test/spec/modules/impactifyBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec, STORAGE, STORAGE_KEY } from 'modules/impactifyBidAdapter.js'; import * as utils from 'src/utils.js'; import sinon from 'sinon'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const BIDDER_CODE = 'impactify'; const BIDDER_ALIAS = ['imp']; diff --git a/test/spec/modules/improvedigitalBidAdapter_spec.js b/test/spec/modules/improvedigitalBidAdapter_spec.js index 4d5038b795e..752b444a6f2 100644 --- a/test/spec/modules/improvedigitalBidAdapter_spec.js +++ b/test/spec/modules/improvedigitalBidAdapter_spec.js @@ -1,9 +1,9 @@ -import {expect} from 'chai'; -import {CONVERTER, spec} from 'modules/improvedigitalBidAdapter.js'; -import {config} from 'src/config.js'; -import {deepClone} from 'src/utils.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; -import {deepSetValue} from '../../../src/utils.js'; +import { expect } from 'chai'; +import { CONVERTER, spec } from 'modules/improvedigitalBidAdapter.js'; +import { config } from 'src/config.js'; +import { deepClone } from 'src/utils.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; +import { deepSetValue } from '../../../src/utils.js'; // load modules that register ORTB processors import 'src/prebid.js'; import 'modules/currency.js'; @@ -12,9 +12,9 @@ import 'modules/multibid/index.js'; import 'modules/priceFloors.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; -import {hook} from '../../../src/hook.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; +import { hook } from '../../../src/hook.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; import * as prebidGlobal from 'src/prebidGlobal.js'; describe('Improve Digital Adapter Tests', function () { @@ -87,8 +87,8 @@ describe('Improve Digital Adapter Tests', function () { const nativeBidRequest = deepClone(simpleBidRequest); nativeBidRequest.mediaTypes = { native: {} }; nativeBidRequest.nativeParams = { - title: {required: true}, - body: {required: true} + title: { required: true }, + body: { required: true } }; const multiFormatBidRequest = deepClone(simpleBidRequest); @@ -233,7 +233,7 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.tmax).not.to.exist; expect(payload.regs).to.not.exist; expect(payload.schain).to.not.exist; - sinon.assert.match(payload.source, {tid: 'mock-tid'}) + sinon.assert.match(payload.source, { tid: 'mock-tid' }) expect(payload.device).to.be.an('object'); expect(payload.user).to.not.exist; sinon.assert.match(payload.imp, [ @@ -247,8 +247,8 @@ describe('Improve Digital Adapter Tests', function () { }, banner: { format: [ - {w: 300, h: 250}, - {w: 160, h: 600}, + { w: 300, h: 250 }, + { w: 160, h: 600 }, ] } }) @@ -283,8 +283,8 @@ describe('Improve Digital Adapter Tests', function () { }), banner: { format: [ - {w: 300, h: 250}, - {w: 160, h: 600}, + { w: 300, h: 250 }, + { w: 160, h: 600 }, ] } }) @@ -298,10 +298,10 @@ describe('Improve Digital Adapter Tests', function () { const nativeReq = JSON.parse(payload.imp[0].native.request); sinon.assert.match(nativeReq, { eventtrackers: [ - {event: 1, methods: [1, 2]}, + { event: 1, methods: [1, 2] }, ], 'assets': [ - sinon.match({'required': 1, 'data': {'type': 2}}) + sinon.match({ 'required': 1, 'data': { 'type': 2 } }) ] }); } @@ -313,11 +313,11 @@ describe('Improve Digital Adapter Tests', function () { const nativeReq = JSON.parse(payload.imp[0].native.request); sinon.assert.match(nativeReq, { eventtrackers: [ - {event: 1, methods: [1, 2]}, + { event: 1, methods: [1, 2] }, ], assets: [ - sinon.match({required: 1, title: {len: 140}}), - sinon.match({required: 1, data: {type: 2}}) + sinon.match({ required: 1, title: { len: 140 } }), + sinon.match({ required: 1, data: { type: 2 } }) ] }) }); @@ -330,7 +330,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should not make native request when no assets', function () { - const requests = updateNativeParams([{...nativeBidRequest, nativeParams: {}}]) + const requests = updateNativeParams([{ ...nativeBidRequest, nativeParams: {} }]) const payload = JSON.parse(spec.buildRequests(requests, {})[0].data); expect(payload.imp[0].native).to.not.exist; }); @@ -349,7 +349,7 @@ describe('Improve Digital Adapter Tests', function () { }); it('should add currency', function () { - config.setConfig({currency: {adServerCurrency: 'JPY'}}); + config.setConfig({ currency: { adServerCurrency: 'JPY' } }); try { const bidRequest = Object.assign({}, simpleBidRequest); const payload = JSON.parse(spec.buildRequests([bidRequest], bidderRequest)[0].data); @@ -430,7 +430,7 @@ describe('Improve Digital Adapter Tests', function () { it('should add CCPA consent string', async function () { const bidRequest = Object.assign({}, simpleBidRequest); - const request = spec.buildRequests([bidRequest], await addFPDToBidderRequest({...bidderRequest, ...{ uspConsent: '1YYY' }})); + const request = spec.buildRequests([bidRequest], await addFPDToBidderRequest({ ...bidderRequest, ...{ uspConsent: '1YYY' } })); const payload = JSON.parse(request[0].data); expect(payload.regs.ext.us_privacy).to.equal('1YYY'); }); @@ -531,12 +531,14 @@ describe('Improve Digital Adapter Tests', function () { bidRequest.params.video = videoParams; const request = spec.buildRequests([bidRequest], {})[0]; const payload = JSON.parse(request.data); - expect(payload.imp[0].video).to.deep.equal({...{ - mimes: ['video/mp4'], - w: bidRequest.mediaTypes.video.playerSize[0], - h: bidRequest.mediaTypes.video.playerSize[1], - }, - ...videoParams}); + expect(payload.imp[0].video).to.deep.equal({ + ...{ + mimes: ['video/mp4'], + w: bidRequest.mediaTypes.video.playerSize[0], + h: bidRequest.mediaTypes.video.playerSize[1], + }, + ...videoParams + }); }); // it('should set video params for multi-format', function() { @@ -560,7 +562,7 @@ describe('Improve Digital Adapter Tests', function () { // Add schain to both locations in the bid bidRequest.ortb2 = { source: { - ext: {schain: schain} + ext: { schain: schain } } }; @@ -569,7 +571,7 @@ describe('Improve Digital Adapter Tests', function () { ...bidderRequestReferrer, ortb2: { source: { - ext: {schain: schain} + ext: { schain: schain } } } }; @@ -589,16 +591,20 @@ describe('Improve Digital Adapter Tests', function () { }] } ]; - const expectedUserObject = { ext: { eids: [{ - source: 'id5-sync.com', - uids: [{ - atype: 1, - id: '1111' - }] - }]}}; + const expectedUserObject = { + ext: { + eids: [{ + source: 'id5-sync.com', + uids: [{ + atype: 1, + id: '1111' + }] + }] + } + }; const request = spec.buildRequests([simpleBidRequest], { ...bidderRequestReferrer, - ortb2: {user: {ext: {eids: eids}}} + ortb2: { user: { ext: { eids: eids } } } })[0]; const payload = JSON.parse(request.data); expect(payload.user).to.deep.equal(expectedUserObject); @@ -616,7 +622,7 @@ describe('Improve Digital Adapter Tests', function () { it('should return one request in a single request mode', function () { getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); - const requests = spec.buildRequests([ simpleBidRequest, instreamBidRequest ], bidderRequest); + const requests = spec.buildRequests([simpleBidRequest, instreamBidRequest], bidderRequest); expect(requests).to.be.an('array'); expect(requests.length).to.equal(1); expect(requests[0].url).to.equal(formatPublisherUrl(AD_SERVER_BASE_URL, 1234)); @@ -629,7 +635,7 @@ describe('Improve Digital Adapter Tests', function () { it('should create one request per endpoint in a single request mode', function () { getConfigStub = sinon.stub(config, 'getConfig'); getConfigStub.withArgs('improvedigital.singleRequest').returns(true); - const requests = spec.buildRequests([ extendBidRequest, simpleBidRequest, instreamBidRequest ], bidderRequest); + const requests = spec.buildRequests([extendBidRequest, simpleBidRequest, instreamBidRequest], bidderRequest); expect(requests).to.be.an('array'); expect(requests.length).to.equal(2); expect(requests[0].url).to.equal(EXTEND_URL); @@ -669,8 +675,8 @@ describe('Improve Digital Adapter Tests', function () { }); it('should not set site when app is defined in FPD', function () { - const ortb2 = {app: {content: 'XYZ'}}; - const request = spec.buildRequests([simpleBidRequest], {...bidderRequest, ortb2})[0]; + const ortb2 = { app: { content: 'XYZ' } }; + const request = spec.buildRequests([simpleBidRequest], { ...bidderRequest, ortb2 })[0]; const payload = JSON.parse(request.data); expect(payload.site).does.not.exist; expect(payload.app).does.exist; @@ -684,8 +690,8 @@ describe('Improve Digital Adapter Tests', function () { expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html'); expect(payload.site.domain).does.exist.and.equal('blah.com'); - const ortb2 = {site: {content: 'ZZZ'}}; - request = spec.buildRequests([simpleBidRequest], await addFPDToBidderRequest({...bidderRequestReferrer, ortb2}))[0]; + const ortb2 = { site: { content: 'ZZZ' } }; + request = spec.buildRequests([simpleBidRequest], await addFPDToBidderRequest({ ...bidderRequestReferrer, ortb2 }))[0]; payload = JSON.parse(request.data); expect(payload.site.content).does.exist.and.equal('ZZZ'); expect(payload.site.page).does.exist.and.equal('https://blah.com/test.html'); @@ -704,7 +710,7 @@ describe('Improve Digital Adapter Tests', function () { it('should set extend params when extend mode enabled from global configuration', function () { getConfigStub = sinon.stub(config, 'getConfig'); const bannerRequest = deepClone(simpleBidRequest); - const keyValues = { testKey: [ 'testValue' ] }; + const keyValues = { testKey: ['testValue'] }; bannerRequest.params.keyValues = keyValues; getConfigStub.withArgs('improvedigital.extend').returns(true); @@ -1103,7 +1109,7 @@ describe('Improve Digital Adapter Tests', function () { function makeRequest(bidderRequest) { return { - ortbRequest: CONVERTER.toORTB({bidderRequest}) + ortbRequest: CONVERTER.toORTB({ bidderRequest }) } } @@ -1272,7 +1278,7 @@ describe('Improve Digital Adapter Tests', function () { }); describe('getUserSyncs', function () { - const serverResponses = [ serverResponse, serverResponseTwoBids ]; + const serverResponses = [serverResponse, serverResponseTwoBids]; const pixelSyncs = [ { type: 'image', url: 'https://link1' }, { type: 'image', url: 'https://link2' }, @@ -1373,7 +1379,7 @@ describe('Improve Digital Adapter Tests', function () { getConfigStub.withArgs('improvedigital.extend').returns(true); spec.buildRequests([simpleBidRequest], {}); const rawResponse = deepClone(serverResponse) - deepSetValue(rawResponse, 'body.ext.responsetimemillis', {a: 1, b: 1, c: 1, d: 1, e: 1}) + deepSetValue(rawResponse, 'body.ext.responsetimemillis', { a: 1, b: 1, c: 1, d: 1, e: 1 }) const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [rawResponse]); const url = basicIframeSyncUrl + '&pbs=1' + '&bidders=a,b,c,d,e' expect(syncs).to.deep.equal([{ type: 'iframe', url }]); diff --git a/test/spec/modules/imuIdSystem_spec.js b/test/spec/modules/imuIdSystem_spec.js index b3cc5ba73ae..527e31a87ea 100644 --- a/test/spec/modules/imuIdSystem_spec.js +++ b/test/spec/modules/imuIdSystem_spec.js @@ -13,9 +13,9 @@ import { } from 'modules/imuIdSystem.js'; import * as utils from 'src/utils.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; describe('imuId module', function () { // let setLocalStorageStub; @@ -54,10 +54,12 @@ describe('imuId module', function () { getLocalStorageStub.withArgs(storageKey).returns('testUid'); getLocalStorageStub.withArgs(storagePpKey).returns('testPpid'); const id = imuIdSubmodule.getId(configParamTestCase); - expect(id).to.be.deep.equal({id: { - imuid: 'testUid', - imppid: 'testPpid' - }}); + expect(id).to.be.deep.equal({ + id: { + imuid: 'testUid', + imppid: 'testPpid' + } + }); }); storageTestCasesForEmpty.forEach(testCase => it('should return the callback when it not exists in local storages', function () { diff --git a/test/spec/modules/inmobiBidAdapter_spec.js b/test/spec/modules/inmobiBidAdapter_spec.js index 9b22cd173d4..a9dc0250fdb 100644 --- a/test/spec/modules/inmobiBidAdapter_spec.js +++ b/test/spec/modules/inmobiBidAdapter_spec.js @@ -571,7 +571,7 @@ describe('The inmobi bidding adapter', function () { } } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.site.domain).to.equal('raapchikgames.com'); expect(ortbRequest.site.publisher.domain).to.equal('inmobi'); expect(ortbRequest.site.page).to.equal('https://raapchikgames.com'); @@ -620,7 +620,7 @@ describe('The inmobi bidding adapter', function () { } } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.device.dnt).to.equal(0); expect(ortbRequest.device.lmt).to.equal(1); expect(ortbRequest.device.js).to.equal(1); @@ -638,7 +638,7 @@ describe('The inmobi bidding adapter', function () { }); it('should properly build a request with source object', async function () { - const expectedSchain = {id: 'prebid'}; + const expectedSchain = { id: 'prebid' }; const ortb2 = { source: { pchain: 'inmobi', @@ -660,7 +660,7 @@ describe('The inmobi bidding adapter', function () { }, }, ]; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.source.ext.schain).to.deep.equal(expectedSchain); expect(ortbRequest.source.pchain).to.equal('inmobi'); }); @@ -749,7 +749,7 @@ describe('The inmobi bidding adapter', function () { } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.regs.coppa).to.equal(1); expect(ortbRequest.regs.ext.gpp).to.equal('gpp_consent_string'); expect(ortbRequest.regs.ext.gpp_sid).to.deep.equal([0, 1, 2]); @@ -1167,7 +1167,7 @@ describe('The inmobi bidding adapter', function () { it('should properly build a request when coppa flag is true', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.regs.coppa).to.equal(1); }); @@ -1175,7 +1175,7 @@ describe('The inmobi bidding adapter', function () { it('should properly build a request when coppa flag is false', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: false}); + config.setConfig({ coppa: false }); const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.regs.coppa).to.equal(0); }); @@ -1223,7 +1223,7 @@ describe('The inmobi bidding adapter', function () { plc: '123a' }, getFloor: inputParams => { - return {currency: 'USD', floor: 1.23, size: '*', mediaType: '*'}; + return { currency: 'USD', floor: 1.23, size: '*', mediaType: '*' }; } } ]; @@ -1271,7 +1271,7 @@ describe('The inmobi bidding adapter', function () { plc: '123a' }, getFloor: inputParams => { - return {currency: 'USD', floor: 1.23, size: '*', mediaType: '*'}; + return { currency: 'USD', floor: 1.23, size: '*', mediaType: '*' }; } } ]; @@ -1326,7 +1326,7 @@ describe('The inmobi bidding adapter', function () { plc: '12456' }, getFloor: inputParams => { - return {currency: 'USD', floor: 1.23, size: '*', mediaType: '*'}; + return { currency: 'USD', floor: 1.23, size: '*', mediaType: '*' }; } }, ]; @@ -1652,9 +1652,9 @@ describe('The inmobi bidding adapter', function () { it('should return an empty array when there is no bid response', async function () { const bidRequests = []; - const response = {seatbid: []}; + const response = { seatbid: [] }; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(0); }); @@ -1673,7 +1673,7 @@ describe('The inmobi bidding adapter', function () { }]; const response = mockResponse('bidId', 1); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.length(1); expect(bids[0].currency).to.deep.equal('USD'); expect(bids[0].mediaType).to.deep.equal('banner'); @@ -1719,7 +1719,7 @@ describe('The inmobi bidding adapter', function () { }]; const response = mockResponse('bidId2', 1); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids[0].currency).to.deep.equal('USD'); expect(bids[0].mediaType).to.deep.equal('banner'); expect(bids[0].requestId).to.deep.equal('bidId2'); @@ -1754,7 +1754,7 @@ describe('The inmobi bidding adapter', function () { }]; const response = mockResponse('bidId', 2); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].currency).to.deep.equal('USD'); @@ -1793,7 +1793,7 @@ describe('The inmobi bidding adapter', function () { }]; const response = mockResponse('bidId', 2); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].currency).to.deep.equal('USD'); @@ -1843,7 +1843,7 @@ describe('The inmobi bidding adapter', function () { }]; const response = mockResponse('bidId', 2); const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(VIDEO); expect(bids[0].currency).to.deep.equal('USD'); @@ -1884,7 +1884,7 @@ describe('The inmobi bidding adapter', function () { const response = mockResponseNative('bidId', 4); const expectedAdmNativeOrtb = JSON.parse(response.seatbid[0].bid[0].adm).native; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(NATIVE); @@ -1939,7 +1939,7 @@ describe('The inmobi bidding adapter', function () { const response = mockResponseNative('bidId', 4); const expectedAdmNativeOrtb = JSON.parse(response.seatbid[0].bid[0].adm).native; const request = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); - const bids = spec.interpretResponse({body: response}, request); + const bids = spec.interpretResponse({ body: response }, request); expect(bids).to.have.lengthOf(1); expect(bids[0].mediaType).to.equal(NATIVE); // testing diff --git a/test/spec/modules/insticatorBidAdapter_spec.js b/test/spec/modules/insticatorBidAdapter_spec.js index cee99ca8c38..520630a6e82 100644 --- a/test/spec/modules/insticatorBidAdapter_spec.js +++ b/test/spec/modules/insticatorBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec, storage } from '../../../modules/insticatorBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js' import { getWinDimensions } from '../../../src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const USER_ID_KEY = 'hb_insticator_uid'; const USER_ID_DUMMY_VALUE = '74f78609-a92d-4cf1-869f-1b244bbfb5d2'; @@ -520,7 +520,7 @@ describe('InsticatorBidAdapter', function () { } } } - const requests = spec.buildRequests([bidRequest], {...bidRequestWithDsa}); + const requests = spec.buildRequests([bidRequest], { ...bidRequestWithDsa }); const data = JSON.parse(requests[0].data); expect(data.regs).to.be.an('object'); expect(data.regs.ext).to.be.an('object'); @@ -619,7 +619,7 @@ describe('InsticatorBidAdapter', function () { const data = JSON.parse(requests[0].data); expect(data.imp[0].bidfloor).to.equal(1); - tempBiddRequest.mediaTypes.banner.format = [ { w: 300, h: 600 }, + tempBiddRequest.mediaTypes.banner.format = [{ w: 300, h: 600 }, ]; const request2 = spec.buildRequests([tempBiddRequest], bidderRequest); const data2 = JSON.parse(request2[0].data); @@ -812,6 +812,136 @@ describe('InsticatorBidAdapter', function () { const data = JSON.parse(requests[0].data); expect(data.site.publisher).to.not.an('object'); }); + + it('should include publisherId as query parameter in endpoint URL', function () { + const tempBiddRequest = { + ...bidRequest, + } + tempBiddRequest.params = { + ...tempBiddRequest.params, + publisherId: '86dd03a1-053f-4e3e-90e7-389070a0c62c' + } + const requests = spec.buildRequests([tempBiddRequest], bidderRequest); + expect(requests[0].url).to.include('publisherId=86dd03a1-053f-4e3e-90e7-389070a0c62c'); + }); + + it('should not include publisherId query param if publisherId is not present', function () { + const tempBiddRequest = { + ...bidRequest, + } + // Ensure no publisherId in params + delete tempBiddRequest.params.publisherId; + const requests = spec.buildRequests([tempBiddRequest], bidderRequest); + expect(requests[0].url).to.not.include('publisherId'); + }); + + it('should not include publisherId query param if publisherId is empty string', function () { + const tempBiddRequest = { + ...bidRequest, + } + tempBiddRequest.params = { + ...tempBiddRequest.params, + publisherId: '' + } + const requests = spec.buildRequests([tempBiddRequest], bidderRequest); + expect(requests[0].url).to.not.include('publisherId'); + }); + + it('should include publisherId query param with custom endpoint URL', function () { + const tempBiddRequest = { + ...bidRequest, + } + tempBiddRequest.params = { + ...tempBiddRequest.params, + publisherId: 'test-publisher-123', + bid_endpoint_request_url: 'https://custom.endpoint.com/v1/bid' + } + const requests = spec.buildRequests([tempBiddRequest], bidderRequest); + expect(requests[0].url).to.equal('https://custom.endpoint.com/v1/bid?publisherId=test-publisher-123'); + }); + + // ORTB 2.6 Ad Pod video params tests + describe('Ad Pod video params', function () { + it('should include Ad Pod params when present in video mediaType', function () { + const adPodBidRequest = { + ...bidRequest, + mediaTypes: { + video: { + mimes: ['video/mp4', 'video/mpeg'], + w: 640, + h: 480, + podid: 'pod-123', + podseq: 1, + poddur: 300, + slotinpod: 1, + mincpmpersec: 0.02, + maxseq: 5, + rqddurs: [15, 30, 60], + }, + }, + }; + const requests = spec.buildRequests([adPodBidRequest], bidderRequest); + const data = JSON.parse(requests[0].data); + + expect(data.imp[0].video).to.have.property('podid', 'pod-123'); + expect(data.imp[0].video).to.have.property('podseq', 1); + expect(data.imp[0].video).to.have.property('poddur', 300); + expect(data.imp[0].video).to.have.property('slotinpod', 1); + expect(data.imp[0].video).to.have.property('mincpmpersec', 0.02); + expect(data.imp[0].video).to.have.property('maxseq', 5); + expect(data.imp[0].video).to.have.property('rqddurs').that.deep.equals([15, 30, 60]); + }); + + it('should not include invalid ORTB 2.6 video params', function () { + const adPodBidRequest = { + ...bidRequest, + mediaTypes: { + video: { + mimes: ['video/mp4'], + w: 640, + h: 480, + podid: '', // invalid - empty string + podseq: -1, // invalid - negative + poddur: 0, // invalid - zero + slotinpod: 5, // invalid - not in [-1, 0, 1, 2] + mincpmpersec: -0.5, // invalid - negative + maxseq: 0, // invalid - zero + rqddurs: [0, -15], // invalid - contains non-positive values + }, + }, + }; + const requests = spec.buildRequests([adPodBidRequest], bidderRequest); + const data = JSON.parse(requests[0].data); + + expect(data.imp[0].video).to.not.have.property('podid'); + expect(data.imp[0].video).to.not.have.property('podseq'); + expect(data.imp[0].video).to.not.have.property('poddur'); + expect(data.imp[0].video).to.not.have.property('slotinpod'); + expect(data.imp[0].video).to.not.have.property('mincpmpersec'); + expect(data.imp[0].video).to.not.have.property('maxseq'); + expect(data.imp[0].video).to.not.have.property('rqddurs'); + }); + + it('should validate slotinpod accepts valid values [-1, 0, 1, 2]', function () { + [-1, 0, 1, 2].forEach(slotValue => { + const adPodBidRequest = { + ...bidRequest, + mediaTypes: { + video: { + mimes: ['video/mp4'], + w: 640, + h: 480, + slotinpod: slotValue, + }, + }, + }; + const requests = spec.buildRequests([adPodBidRequest], bidderRequest); + const data = JSON.parse(requests[0].data); + + expect(data.imp[0].video).to.have.property('slotinpod', slotValue); + }); + }); + }); }); describe('interpretResponse', function () { @@ -929,7 +1059,7 @@ describe('InsticatorBidAdapter', function () { cpm: 0.5, currency: 'USD', netRevenue: true, - ttl: 60, + ttl: 60, // MIN(60, 300) = 60 - bid.exp is upper bound width: 300, height: 200, mediaType: 'banner', @@ -937,7 +1067,8 @@ describe('InsticatorBidAdapter', function () { adUnitCode: 'adunit-code-1', meta: { advertiserDomains: ['test1.com'], - test: 1 + test: 1, + seat: 'some-dsp' } }, { @@ -953,7 +1084,8 @@ describe('InsticatorBidAdapter', function () { meta: { advertiserDomains: [ 'test2.com' - ] + ], + seat: 'some-dsp' }, ad: 'adm2', adUnitCode: 'adunit-code-2', @@ -971,7 +1103,8 @@ describe('InsticatorBidAdapter', function () { meta: { advertiserDomains: [ 'test3.com' - ] + ], + seat: 'some-dsp' }, ad: 'adm3', adUnitCode: 'adunit-code-3', @@ -996,6 +1129,515 @@ describe('InsticatorBidAdapter', function () { delete response.body.seatbid; expect(spec.interpretResponse(response, bidRequests)).to.have.length(0); }); + + it('should return empty response for 204 No Content (undefined body)', function () { + const response = { body: undefined }; + expect(spec.interpretResponse(response, bidRequests)).to.have.length(0); + }); + + it('should return empty response for 204 No Content (null body)', function () { + const response = { body: null }; + expect(spec.interpretResponse(response, bidRequests)).to.have.length(0); + }); + + it('should return empty response for empty object body', function () { + const response = { body: {} }; + expect(spec.interpretResponse(response, bidRequests)).to.have.length(0); + }); + + // ORTB 2.6 Response Fields Tests + describe('ORTB 2.6 response fields', function () { + const ortb26BidRequests = { + method: 'POST', + url: 'https://ex.ingage.tech/v1/openrtb', + options: { + contentType: 'application/json', + withCredentials: true, + }, + data: '', + bidderRequest: { + bidderRequestId: '22edbae2733bf6', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', + timeout: 300, + bids: [ + { + bidder: 'insticator', + params: { + adUnitId: '1a2b3c4d5e6f1a2b3c4d' + }, + adUnitCode: 'adunit-code-1', + sizes: [[300, 250]], + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + bidId: 'bid1', + } + ] + } + }; + + it('should map category (cat) to meta.primaryCatId and meta.secondaryCatIds', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + cat: ['IAB1', 'IAB2-1', 'IAB3'], + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse.meta).to.have.property('primaryCatId', 'IAB1'); + expect(bidResponse.meta).to.have.property('secondaryCatIds').that.deep.equals(['IAB2-1', 'IAB3']); + }); + + it('should map single category without secondaryCatIds', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + cat: ['IAB1'], + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse.meta).to.have.property('primaryCatId', 'IAB1'); + expect(bidResponse.meta).to.not.have.property('secondaryCatIds'); + }); + + it('should map seat to meta.seat', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-seat-123', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + adomain: ['test.com'], + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse.meta).to.have.property('seat', 'dsp-seat-123'); + }); + + it('should map creative attributes (attr) to meta.attr', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + attr: [1, 2, 3], + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse.meta).to.have.property('attr').that.deep.equals([1, 2, 3]); + }); + + it('should map dealid to bidResponse.dealId', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + dealid: 'deal-abc-123', + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse).to.have.property('dealId', 'deal-abc-123'); + }); + + it('should map billing URL (burl) to bidResponse.burl', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + burl: 'https://billing.example.com/win?price=${AUCTION_PRICE}', + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse).to.have.property('burl', 'https://billing.example.com/win?price=${AUCTION_PRICE}'); + }); + + it('should map notice URL (nurl) to bidResponse.nurl', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + nurl: 'https://win.example.com/notify?price=${AUCTION_PRICE}', + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + expect(bidResponse).to.have.property('nurl', 'https://win.example.com/notify?price=${AUCTION_PRICE}'); + }); + + it('should map video duration (dur) to bidResponse.video.durationSeconds', function () { + const videoBidRequests = { + ...ortb26BidRequests, + bidderRequest: { + ...ortb26BidRequests.bidderRequest, + bids: [{ + ...ortb26BidRequests.bidderRequest.bids[0], + mediaTypes: { + video: { + mimes: ['video/mp4'], + playerSize: [[640, 480]], + } + } + }] + } + }; + + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 640, + h: 480, + adm: '', + dur: 30, + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, videoBidRequests)[0]; + + expect(bidResponse).to.have.property('video'); + expect(bidResponse.video).to.have.property('durationSeconds', 30); + }); + + it('should set video.durationSeconds and not set video.context for instream video', function () { + const instreamBidRequests = { + ...ortb26BidRequests, + bidderRequest: { + ...ortb26BidRequests.bidderRequest, + bids: [{ + ...ortb26BidRequests.bidderRequest.bids[0], + mediaTypes: { + video: { + mimes: ['video/mp4'], + playerSize: [[640, 480]], + context: 'instream', + } + } + }] + } + }; + + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 640, + h: 480, + adm: '', + dur: 30, + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, instreamBidRequests)[0]; + + expect(bidResponse).to.have.property('video'); + expect(bidResponse.video).to.have.property('durationSeconds', 30); + expect(bidResponse.video).to.not.have.property('context'); + }); + + it('should use MIN of bid.exp and BID_TTL for ttl (bid.exp is upper bound)', function () { + // When bid.exp (60) is less than BID_TTL (300), use 60 + const responseWithLowExp = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + exp: 60, + }] + }] + } + }; + const bidResponseLow = spec.interpretResponse(responseWithLowExp, ortb26BidRequests)[0]; + expect(bidResponseLow.ttl).to.equal(60); // MIN(60, 300) = 60 + + // When bid.exp (600) is greater than BID_TTL (300), use 300 + const responseWithHighExp = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + exp: 600, + }] + }] + } + }; + const bidResponseHigh = spec.interpretResponse(responseWithHighExp, ortb26BidRequests)[0]; + expect(bidResponseHigh.ttl).to.equal(300); // MIN(600, 300) = 300 + }); + + it('should default ttl to BID_TTL when bid.exp is not provided', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'adm1', + // no exp field + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.ttl).to.equal(300); // defaults to configTTL when no bid.exp + }); + + it('should include all ORTB 2.6 fields in a single response', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'full-dsp', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 2.5, + w: 300, + h: 250, + adm: 'adm1', + adomain: ['advertiser.com'], + cat: ['IAB1', 'IAB2'], + attr: [1, 2], + dealid: 'premium-deal', + burl: 'https://billing.example.com/win', + exp: 450, + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + + // Check all ORTB 2.6 fields + expect(bidResponse.meta.advertiserDomains).to.deep.equal(['advertiser.com']); + expect(bidResponse.meta.primaryCatId).to.equal('IAB1'); + expect(bidResponse.meta.secondaryCatIds).to.deep.equal(['IAB2']); + expect(bidResponse.meta.seat).to.equal('full-dsp'); + expect(bidResponse.meta.attr).to.deep.equal([1, 2]); + expect(bidResponse.dealId).to.equal('premium-deal'); + expect(bidResponse.burl).to.equal('https://billing.example.com/win'); + expect(bidResponse.ttl).to.equal(300); // MIN(450, 300) = 300 - bid.exp is upper bound + }); + + // Media Type Detection Tests + describe('media type detection', function () { + it('should detect video using mtype=2 (ORTB 2.6 standard)', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: 'some non-vast content', + mtype: 2, // video + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.mediaType).to.equal('video'); + }); + + it('should detect banner using mtype=1 (ORTB 2.6 standard)', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: '', // VAST content but mtype says banner + mtype: 1, // banner + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.mediaType).to.equal('banner'); + }); + + it('should detect video using case-insensitive VAST detection', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: '', // lowercase vast + // no mtype + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.mediaType).to.equal('video'); + }); + + it('should default to banner when no video signals present', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: '
banner ad
', + // no mtype, no VAST + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.mediaType).to.equal('banner'); + }); + + it('should detect banner when VAST-like content is inside script tag', function () { + const response = { + body: { + id: '22edbae2733bf6', + seatbid: [{ + seat: 'dsp-1', + bid: [{ + impid: 'bid1', + crid: 'crid1', + price: 1.0, + w: 300, + h: 250, + adm: '
banner
', + // no mtype + }] + }] + } + }; + const bidResponse = spec.interpretResponse(response, ortb26BidRequests)[0]; + expect(bidResponse.mediaType).to.equal('banner'); + }); + }); + }); }); describe('getUserSyncs', function () { @@ -1157,7 +1799,8 @@ describe('InsticatorBidAdapter', function () { dsaparams: [1, 2] }] } - }} + } + } }, } }; diff --git a/test/spec/modules/instreamTracking_spec.js b/test/spec/modules/instreamTracking_spec.js index db1d931e9a2..e4fca4e8b87 100644 --- a/test/spec/modules/instreamTracking_spec.js +++ b/test/spec/modules/instreamTracking_spec.js @@ -20,11 +20,11 @@ function enableInstreamTracking(regex) { maxWindow: 10, pollingFreq: 0 }, - regex && {urlPattern: regex}, + regex && { urlPattern: regex }, )); } -function mockPerformanceApi({adServerCallSent, videoPresent}) { +function mockPerformanceApi({ adServerCallSent, videoPresent }) { const performanceStub = sandbox.stub(window.performance, 'getEntriesByType'); const entries = [{ name: 'https://domain.com/img.png', @@ -105,21 +105,21 @@ function mockBidRequest(adUnit, bidResponse) { function getMockInput(mediaType) { const bannerAdUnit = { code: 'banner', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, sizes: [[300, 250]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] + bids: [{ bidder: BIDDER_CODE, params: { placementId: 'id' } }] }; const outStreamAdUnit = { code: 'video-' + OUTSTREAM, - mediaTypes: {video: {playerSize: [640, 480], context: OUTSTREAM}}, + mediaTypes: { video: { playerSize: [640, 480], context: OUTSTREAM } }, sizes: [[640, 480]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] + bids: [{ bidder: BIDDER_CODE, params: { placementId: 'id' } }] }; const inStreamAdUnit = { code: 'video-' + INSTREAM, - mediaTypes: {video: {playerSize: [640, 480], context: INSTREAM}}, + mediaTypes: { video: { playerSize: [640, 480], context: INSTREAM } }, sizes: [[640, 480]], - bids: [{bidder: BIDDER_CODE, params: {placementId: 'id'}}] + bids: [{ bidder: BIDDER_CODE, params: { placementId: 'id' } }] }; let adUnit; @@ -148,7 +148,7 @@ function getMockInput(mediaType) { describe('Instream Tracking', function () { beforeEach(function () { sandbox = sinon.createSandbox(); - clock = sandbox.useFakeTimers({shouldClearNativeTimers: true}); + clock = sandbox.useFakeTimers({ shouldClearNativeTimers: true }); }); afterEach(function () { @@ -168,7 +168,7 @@ describe('Instream Tracking', function () { it('run only if instream bids are present', function () { enableInstreamTracking(); - assert.isNotOk(trackInstreamDeliveredImpressions({adUnits: [], bidsReceived: [], bidderRequests: []})); + assert.isNotOk(trackInstreamDeliveredImpressions({ adUnits: [], bidsReceived: [], bidderRequests: [] })); }); it('checks for instream bids', function () { @@ -198,7 +198,7 @@ describe('Instream Tracking', function () { it('BID WON event is not emitted when ad server call is sent', function () { enableInstreamTracking(); - mockPerformanceApi({adServerCallSent: true}); + mockPerformanceApi({ adServerCallSent: true }); clock.tick(10); assert.isNotOk(spyEventsOn.calledWith('bidWon')); }); @@ -207,7 +207,7 @@ describe('Instream Tracking', function () { enableInstreamTracking(/cache/); const bidWonSpy = sandbox.spy(); events.on('bidWon', bidWonSpy); - mockPerformanceApi({adServerCallSent: true, videoPresent: true}); + mockPerformanceApi({ adServerCallSent: true, videoPresent: true }); trackInstreamDeliveredImpressions(getMockInput(INSTREAM)); clock.tick(10); diff --git a/test/spec/modules/insuradsBidAdapter_spec.js b/test/spec/modules/insuradsBidAdapter_spec.js new file mode 100644 index 00000000000..1b321493c56 --- /dev/null +++ b/test/spec/modules/insuradsBidAdapter_spec.js @@ -0,0 +1,737 @@ +import { expect } from 'chai'; +import { + spec, STORAGE, getInsurAdsLocalStorage, getGzipSetting, +} from 'modules/insuradsBidAdapter.js'; +import sinon from 'sinon'; +import { getAmxId } from '../../../libraries/nexx360Utils/index.js'; +const sandbox = sinon.createSandbox(); + +describe('InsurAds bid adapter tests', () => { + const DEFAULT_OPTIONS = { + gdprConsent: { + gdprApplies: true, + consentString: 'BOzZdA0OzZdA0AGABBENDJ-AAAAvh7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__79__3z3_9pxP78k89r7337Mw_v-_v-b7JCPN_Y3v-8Kg', + vendorData: {}, + }, + refererInfo: { + referer: 'https://www.prebid.org', + canonicalUrl: 'https://www.prebid.org/the/link/to/the/page', + }, + uspConsent: '1112223334', + userId: { id5id: { uid: '1111' } }, + schain: { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'exchange1.com', + sid: '1234', + hp: 1, + rid: 'bid-request-1', + name: 'publisher', + domain: 'publisher.com', + }], + }, + }; + + it('We test getGzipSettings', () => { + const output = getGzipSetting(); + expect(output).to.be.a('boolean'); + }); + + describe('isBidRequestValid()', () => { + let bannerBid; + beforeEach(() => { + bannerBid = { + bidder: 'nexx360', + mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } }, + adUnitCode: 'div-1', + transactionId: '70bdc37e-9475-4b27-8c74-4634bdc2ee66', + sizes: [[300, 250], [300, 600]], + bidId: '4906582fc87d0c', + bidderRequestId: '332fda16002dbe', + auctionId: '98932591-c822-42e3-850e-4b3cf748d063', + } + }); + + it('We verify isBidRequestValid with unvalid adUnitName', () => { + bannerBid.params = { adUnitName: 1 }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid with empty adUnitName', () => { + bannerBid.params = { adUnitName: '' }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid with unvalid adUnitPath', () => { + bannerBid.params = { adUnitPath: 1 }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid with unvalid divId', () => { + bannerBid.params = { divId: 1 }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid unvalid allBids', () => { + bannerBid.params = { allBids: 1 }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid with uncorrect tagid', () => { + bannerBid.params = { 'tagid': 'luvxjvgn' }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(false); + }); + + it('We verify isBidRequestValid with correct tagId', () => { + bannerBid.params = { 'tagId': 'luvxjvgn' }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(true); + }); + + it('We verify isBidRequestValid with correct placement', () => { + bannerBid.params = { 'placement': 'testad' }; + expect(spec.isBidRequestValid(bannerBid)).to.be.equal(true); + }); + }); + + describe('getInsurAdsLocalStorage disabled', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => false); + }); + it('We test if we get the nexx360Id', () => { + const output = getInsurAdsLocalStorage(); + expect(output).to.be.eql(null); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('getInsurAdsLocalStorage enabled but nothing', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => null); + }); + it('We test if we get the nexx360Id', () => { + const output = getInsurAdsLocalStorage(); + expect(typeof output.nexx360Id).to.be.eql('string'); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('getInsurAdsLocalStorage enabled but wrong payload', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => '{"nexx360Id":"5ad89a6e-7801-48e7-97bb-fe6f251f6cb4",}'); + }); + it('We test if we get the nexx360Id', () => { + const output = getInsurAdsLocalStorage(); + expect(output).to.be.eql(null); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('getInsurAdsLocalStorage enabled', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => '{"nexx360Id":"5ad89a6e-7801-48e7-97bb-fe6f251f6cb4"}'); + }); + it('We test if we get the nexx360Id', () => { + const output = getInsurAdsLocalStorage(); + expect(output.nexx360Id).to.be.eql('5ad89a6e-7801-48e7-97bb-fe6f251f6cb4'); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('getAmxId() with localStorage enabled and data not set', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => null); + }); + it('We test if we get the amxId', () => { + const output = getAmxId(STORAGE, 'nexx360'); + expect(output).to.be.eql(null); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('getAmxId() with localStorage enabled and data set', () => { + before(() => { + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => 'abcdef'); + }); + it('We test if we get the amxId', () => { + const output = getAmxId(STORAGE, 'nexx360'); + expect(output).to.be.eql('abcdef'); + }); + after(() => { + sandbox.restore() + }); + }); + + describe('buildRequests()', () => { + before(() => { + const documentStub = sandbox.stub(document, 'getElementById'); + documentStub.withArgs('div-1').returns({ + offsetWidth: 200, + offsetHeight: 250, + style: { + maxWidth: '400px', + maxHeight: '350px', + }, + getBoundingClientRect() { return { width: 200, height: 250 }; } + }); + sandbox.stub(STORAGE, 'localStorageIsEnabled').callsFake(() => true); + sandbox.stub(STORAGE, 'setDataInLocalStorage'); + sandbox.stub(STORAGE, 'getDataFromLocalStorage').callsFake((key) => 'abcdef'); + }); + describe('We test with a multiple display bids', () => { + const sampleBids = [ + { + bidder: 'nexx360', + params: { + tagId: 'luvxjvgn', + divId: 'div-1', + adUnitName: 'header-ad', + adUnitPath: '/12345/nexx360/Homepage/HP/Header-Ad', + }, + ortb2Imp: { + ext: { + gpid: '/12345/nexx360/Homepage/HP/Header-Ad', + } + }, + adUnitCode: 'header-ad-1234', + transactionId: '469a570d-f187-488d-b1cb-48c1a2009be9', + sizes: [[300, 250], [300, 600]], + bidId: '44a2706ac3574', + bidderRequestId: '359bf8a3c06b2e', + auctionId: '2e684815-b44e-4e04-b812-56da54adbe74', + }, + { + bidder: 'nexx360', + params: { + placement: 'testPlacement', + allBids: true, + }, + mediaTypes: { + banner: { + sizes: [[728, 90], [970, 250]] + } + }, + + adUnitCode: 'div-2-abcd', + transactionId: '6196885d-4e76-40dc-a09c-906ed232626b', + sizes: [[728, 90], [970, 250]], + bidId: '5ba94555219a03', + bidderRequestId: '359bf8a3c06b2e', + auctionId: '2e684815-b44e-4e04-b812-56da54adbe74', + } + ]; + const bidderRequest = { + bidderCode: 'nexx360', + auctionId: '2e684815-b44e-4e04-b812-56da54adbe74', + bidderRequestId: '359bf8a3c06b2e', + refererInfo: { + reachedTop: true, + isAmp: false, + numIframes: 0, + stack: [ + 'https://test.nexx360.io/adapter/index.html' + ], + topmostLocation: 'https://test.nexx360.io/adapter/index.html', + location: 'https://test.nexx360.io/adapter/index.html', + canonicalUrl: null, + page: 'https://test.nexx360.io/adapter/index.html', + domain: 'test.nexx360.io', + ref: null, + legacy: { + reachedTop: true, + isAmp: false, + numIframes: 0, + stack: [ + 'https://test.nexx360.io/adapter/index.html' + ], + referer: 'https://test.nexx360.io/adapter/index.html', + canonicalUrl: null + }, + }, + gdprConsent: { + gdprApplies: true, + consentString: 'CPhdLUAPhdLUAAKAsAENCmCsAP_AAE7AAAqIJFNd_H__bW9r-f5_aft0eY1P9_r37uQzDhfNk-8F3L_W_LwX52E7NF36tq4KmR4ku1LBIUNlHMHUDUmwaokVryHsak2cpzNKJ7BEknMZOydYGF9vmxtj-QKY7_5_d3bx2D-t_9v239z3z81Xn3d53-_03LCdV5_9Dfn9fR_bc9KPt_58v8v8_____3_e__3_7997BIiAaADgAJYBnwEeAJXAXmAwQBj4DtgHcgPBAeKBIgAA.YAAAAAAAAAAA', + } + }; + it('We perform a test with 2 display adunits', () => { + const displayBids = structuredClone(sampleBids); + displayBids[0].mediaTypes = { + banner: { + sizes: [[300, 250], [300, 600]] + } + }; + const request = spec.buildRequests(displayBids, bidderRequest); + const requestContent = request.data; + expect(request).to.have.property('method').and.to.equal('POST'); + const expectedRequest = { + imp: [ + { + id: '44a2706ac3574', + banner: { + topframe: 0, + format: [ + { w: 300, h: 250 }, + { w: 300, h: 600 }, + ], + }, + secure: 1, + tagid: 'header-ad-1234', + ext: { + adUnitCode: 'header-ad-1234', + gpid: '/12345/nexx360/Homepage/HP/Header-Ad', + divId: 'div-1', + dimensions: { + slotW: 200, + slotH: 250, + cssMaxW: '400px', + cssMaxH: '350px', + }, + nexx360: { + tagId: 'luvxjvgn', + adUnitName: 'header-ad', + adUnitPath: '/12345/nexx360/Homepage/HP/Header-Ad', + divId: 'div-1', + }, + adUnitName: 'header-ad', + adUnitPath: '/12345/nexx360/Homepage/HP/Header-Ad', + }, + }, + { + id: '5ba94555219a03', + banner: { + topframe: 0, + format: [ + { w: 728, h: 90 }, + { w: 970, h: 250 }, + ], + }, + secure: 1, + tagid: 'div-2-abcd', + ext: { + adUnitCode: 'div-2-abcd', + divId: 'div-2-abcd', + nexx360: { + placement: 'testPlacement', + divId: 'div-2-abcd', + allBids: true, + }, + }, + }, + ], + id: requestContent.id, + test: 0, + ext: { + version: requestContent.ext.version, + source: 'prebid.js', + pageViewId: requestContent.ext.pageViewId, + bidderVersion: '7.1', + localStorage: { amxId: 'abcdef' }, + sessionId: requestContent.ext.sessionId, + requestCounter: 0, + }, + cur: [ + 'USD', + ], + user: { + ext: { + eids: [ + { + source: 'amxdt.net', + uids: [ + { + id: 'abcdef', + atype: 1, + } + ] + } + ] + } + }, + }; + expect(requestContent).to.be.eql(expectedRequest); + }); + + if (FEATURES.VIDEO) { + it('We perform a test with a multiformat adunit', () => { + const multiformatBids = structuredClone(sampleBids); + multiformatBids[0].mediaTypes = { + banner: { + sizes: [[300, 250], [300, 600]] + }, + video: { + context: 'outstream', + playerSize: [640, 480], + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6, 7, 8], + playbackmethod: [2], + skip: 1, + playback_method: ['auto_play_sound_off'] + } + }; + const request = spec.buildRequests(multiformatBids, bidderRequest); + const video = request.data.imp[0].video; + const expectedVideo = { + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6, 7, 8], + playbackmethod: [2], + skip: 1, + w: 640, + h: 480, + ext: { + playerSize: [640, 480], + context: 'outstream', + }, + }; + expect(video).to.eql(expectedVideo); + }); + + it('We perform a test with a instream adunit', () => { + const videoBids = structuredClone(sampleBids); + videoBids[0].mediaTypes = { + video: { + context: 'instream', + playerSize: [640, 480], + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6], + playbackmethod: [2], + skip: 1 + } + }; + const request = spec.buildRequests(videoBids, bidderRequest); + const requestContent = request.data; + expect(request).to.have.property('method').and.to.equal('POST'); + expect(requestContent.imp[0].video.ext.context).to.be.eql('instream'); + expect(requestContent.imp[0].video.playbackmethod[0]).to.be.eql(2); + }); + } + }); + after(() => { + sandbox.restore() + }); + }); + + describe('We test interpretResponse', () => { + it('empty response', () => { + const response = { + body: '' + }; + const output = spec.interpretResponse(response); + expect(output.length).to.be.eql(0); + }); + it('banner responses with adm', () => { + const response = { + body: { + id: 'a8d3a675-a4ba-4d26-807f-c8f2fad821e0', + cur: 'USD', + seatbid: [ + { + bid: [ + { + id: '4427551302944024629', + impid: '226175918ebeda', + price: 1.5, + adomain: [ + 'http://prebid.org', + ], + crid: '98493581', + ssp: 'appnexus', + h: 600, + w: 300, + adm: '
TestAd
', + cat: [ + 'IAB3-1', + ], + ext: { + adUnitCode: 'div-1', + mediaType: 'banner', + adUrl: 'https://fast.nexx360.io/cache?uuid=fdddcebc-1edf-489d-880d-1418d8bdc493', + ssp: 'appnexus', + }, + }, + ], + seat: 'appnexus', + }, + ], + ext: { + id: 'de3de7c7-e1cf-4712-80a9-94eb26bfc718', + cookies: [], + }, + }, + }; + const output = spec.interpretResponse(response); + const expectedOutput = [{ + requestId: '226175918ebeda', + cpm: 1.5, + width: 300, + height: 600, + creativeId: '98493581', + currency: 'USD', + netRevenue: true, + ttl: 120, + mediaType: 'banner', + meta: { + advertiserDomains: [ + 'http://prebid.org', + ], + demandSource: 'appnexus', + }, + ad: '
TestAd
', + }]; + expect(output).to.eql(expectedOutput); + }); + + it('instream responses', () => { + const response = { + body: { + id: '2be64380-ba0c-405a-ab53-51f51c7bde51', + cur: 'USD', + seatbid: [ + { + bid: [ + { + id: '8275140264321181514', + impid: '263cba3b8bfb72', + price: 5, + adomain: [ + 'appnexus.com', + ], + crid: '97517771', + h: 1, + w: 1, + adm: 'vast', + ext: { + mediaType: 'instream', + ssp: 'appnexus', + adUnitCode: 'video1', + }, + }, + ], + seat: 'appnexus', + }, + ], + ext: { + cookies: [], + }, + }, + }; + + const output = spec.interpretResponse(response); + const expectedOutput = [{ + requestId: '263cba3b8bfb72', + cpm: 5, + width: 1, + height: 1, + creativeId: '97517771', + currency: 'USD', + netRevenue: true, + ttl: 120, + mediaType: 'video', + meta: { advertiserDomains: ['appnexus.com'], demandSource: 'appnexus' }, + vastXml: 'vast', + }]; + expect(output).to.eql(expectedOutput); + }); + + it('outstream responses', () => { + const response = { + body: { + id: '40c23932-135e-4602-9701-ca36f8d80c07', + cur: 'USD', + seatbid: [ + { + bid: [ + { + id: '1186971142548769361', + impid: '4ce809b61a3928', + price: 5, + adomain: [ + 'appnexus.com', + ], + crid: '97517771', + h: 1, + w: 1, + adm: 'vast', + ext: { + mediaType: 'outstream', + ssp: 'appnexus', + adUnitCode: 'div-1', + divId: 'div-1', + }, + }, + ], + seat: 'appnexus', + }, + ], + ext: { + cookies: [], + }, + }, + }; + + const output = spec.interpretResponse(response); + const expectedOutut = [{ + requestId: '4ce809b61a3928', + cpm: 5, + width: 1, + height: 1, + creativeId: '97517771', + currency: 'USD', + netRevenue: true, + divId: 'div-1', + ttl: 120, + mediaType: 'video', + meta: { advertiserDomains: ['appnexus.com'], demandSource: 'appnexus' }, + vastXml: 'vast', + renderer: output[0].renderer, + }]; + expect(output).to.eql(expectedOutut); + }); + + it('native responses', () => { + const response = { + body: { + id: '3c0290c1-6e75-4ef7-9e37-17f5ebf3bfa3', + cur: 'USD', + seatbid: [ + { + bid: [ + { + id: '6624930625245272225', + impid: '23e11d845514bb', + price: 10, + adomain: [ + 'prebid.org', + ], + crid: '97494204', + h: 1, + w: 1, + cat: [ + 'IAB3-1', + ], + ext: { + mediaType: 'native', + ssp: 'appnexus', + adUnitCode: '/19968336/prebid_native_example_1', + }, + adm: '{"ver":"1.2","assets":[{"id":1,"img":{"url":"https:\\/\\/vcdn.adnxs.com\\/p\\/creative-image\\/f8\\/7f\\/0f\\/13\\/f87f0f13-230c-4f05-8087-db9216e393de.jpg","w":989,"h":742,"ext":{"appnexus":{"prevent_crop":0}}}},{"id":0,"title":{"text":"This is a Prebid Native Creative"}},{"id":2,"data":{"value":"Prebid.org"}}],"link":{"url":"https:\\/\\/ams3-ib.adnxs.com\\/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQKZS4ZZl5vVbR6p-A-MwnyTZ7QVkAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAgMCAAAAALoAURe69gAAAAA.\\/bcr=AAAAAAAA8D8=\\/pp=${AUCTION_PRICE}\\/cnd=%21JBC72Aj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJQU1TMzo2MTM1QNAwSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeACJAQAAAAAAAAAA\\/cca=OTMyNSNBTVMzOjYxMzU=\\/bn=97062\\/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html"},"eventtrackers":[{"event":1,"method":1,"url":"https:\\/\\/ams3-ib.adnxs.com\\/it?an_audit=0&referrer=https%3A%2F%2Ftest.nexx360.io%2Fadapter%2Fnative%2Ftest.html&e=wqT_3QKJCqAJBQAAAwDWAAUBCNnbl6AGEKalhbfZzPn6WxjH1PqbsJzMzyQqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXim9gWAAQGKAQNVU0SSAQEG9F4BmAEBoAEBqAEBsAEAuAECwAEDyAEC0AEJ2AEA4AEA8AEAigIpdWYoJ2EnLCAyNTI5ODg1LCAwKTt1ZigncicsIDk3NDk0MjA0LCAwKTuSAvEDIS0xRDNJQWo4LUx3S0VMekp2aTRZQUNDYzhWc3dBRGdBUUFSSTdVaFE0dEduQmxnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYSUtWbWViSmZJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpnREFib0RDVUZOVXpNNk5qRXpOZUFEMERDSUJBQ1FCQUNZQkFIQkJBQUFBQUFBQUFBQXlRUUFBCQscQUFOZ0VBUEURlSxBQUFDSUJmY3ZxUVUBDQRBQQGoCDdFRgEKCQEMREJCUQkKAQEAeRUoAUwyKAAAWi4oALg0QVhBaEQzd0JhTEQzd0w0QmQyMG1nR0NCZ05WVTBTSUJnQ1FCZ0dZQmdDaEJnQQFONEFBQ1JBcUFZQnNnWWtDHXQARR0MAEcdDABJHQw8dUFZS5oClQEhSkJDNzJBajL1ASRuUEZiSUFRb0FEFfhUa1FEb0pRVTFUTXpvMk1UTTFRTkF3UxFRDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQwQZUFDSkEdEMjYAvfpA-ACrZhI6gIwaHR0cHM6Ly90ZXN0Lm5leHgzNjAuaW8vYWRhcHRlci9uYXRpdmUJH_CaaHRtbIADAIgDAZADAJgDFKADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMDgAQAkgQJL29wZW5ydGIymAQAqAQAsgQMCAAQABgAIAAwADgAuAQAwASA2rgiyAQA0gQOOTMyNSNBTVMzOjYxMzXaBAIIAeAEAPAEvMm-LvoEEgkAAABAPG1IQBEAAACgV8oCQIgFAZgFAKAF______8BBbABqgUkM2MwMjkwYzEtNmU3NS00ZWY3LTllMzctMTdmNWViZjNiZmEzwAUAyQWJFxTwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBAdpg4AYM8gYCCACABwGIBwCgB0HIB6b2BdIHDRVkASYI2gcGAV1oGADgBwDqBwIIAPAHAIoIAhAAlQgAAIA_mAgB&s=ccf63f2e483a37091d2475d895e7cf7c911d1a78&pp=${AUCTION_PRICE}"}]}', + }, + ], + seat: 'appnexus', + }, + ], + ext: { + cookies: [], + }, + }, + }; + + const output = spec.interpretResponse(response); + const expectOutput = [{ + requestId: '23e11d845514bb', + cpm: 10, + width: 1, + height: 1, + creativeId: '97494204', + currency: 'USD', + netRevenue: true, + ttl: 120, + mediaType: 'native', + meta: { + advertiserDomains: [ + 'prebid.org', + ], + demandSource: 'appnexus', + }, + native: { + ortb: { + ver: '1.2', + assets: [ + { + id: 1, + img: { + url: 'https://vcdn.adnxs.com/p/creative-image/f8/7f/0f/13/f87f0f13-230c-4f05-8087-db9216e393de.jpg', + w: 989, + h: 742, + ext: { + appnexus: { + prevent_crop: 0, + }, + }, + }, + }, + { + id: 0, + title: { + text: 'This is a Prebid Native Creative', + }, + }, + { + id: 2, + data: { + value: 'Prebid.org', + }, + }, + ], + link: { + url: 'https://ams3-ib.adnxs.com/click?AAAAAAAAJEAAAAAAAAAkQAAAAAAAACRAAAAAAAAAJEAAAAAAAAAkQKZS4ZZl5vVbR6p-A-MwnyTZ7QVkAAAAAOLoyQBtJAAAbSQAAAIAAAC8pM8FnPgWAAAAAABVU0QAVVNEAAEAAQBNXQAAAAABAgMCAAAAALoAURe69gAAAAA./bcr=AAAAAAAA8D8=/pp=${AUCTION_PRICE}/cnd=%21JBC72Aj8-LwKELzJvi4YnPFbIAQoADEAAAAAAAAkQDoJQU1TMzo2MTM1QNAwSQAAAAAAAPA_UQAAAAAAAAAAWQAAAAAAAAAAYQAAAAAAAAAAaQAAAAAAAAAAcQAAAAAAAAAAeACJAQAAAAAAAAAA/cca=OTMyNSNBTVMzOjYxMzU=/bn=97062/clickenc=http%3A%2F%2Fprebid.org%2Fdev-docs%2Fshow-native-ads.html', + }, + eventtrackers: [ + { + event: 1, + method: 1, + url: 'https://ams3-ib.adnxs.com/it?an_audit=0&referrer=https%3A%2F%2Ftest.nexx360.io%2Fadapter%2Fnative%2Ftest.html&e=wqT_3QKJCqAJBQAAAwDWAAUBCNnbl6AGEKalhbfZzPn6WxjH1PqbsJzMzyQqNgkAAAECCCRAEQEHEAAAJEAZEQkAIREJACkRCQAxEQmoMOLRpwY47UhA7UhIAlC8yb4uWJzxW2AAaM26dXim9gWAAQGKAQNVU0SSAQEG9F4BmAEBoAEBqAEBsAEAuAECwAEDyAEC0AEJ2AEA4AEA8AEAigIpdWYoJ2EnLCAyNTI5ODg1LCAwKTt1ZigncicsIDk3NDk0MjA0LCAwKTuSAvEDIS0xRDNJQWo4LUx3S0VMekp2aTRZQUNDYzhWc3dBRGdBUUFSSTdVaFE0dEduQmxnQVlQX19fXzhQYUFCd0FYZ0JnQUVCaUFFQmtBRUJtQUVCb0FFQnFBRURzQUVBdVFIenJXcWtBQUFrUU1FQjg2MXFwQUFBSkVESkFYSUtWbWViSmZJXzJRRUFBQUFBQUFEd1AtQUJBUFVCQUFBQUFKZ0NBS0FDQUxVQ0FBQUFBTDBDQUFBQUFNQUNBY2dDQWRBQ0FkZ0NBZUFDQU9nQ0FQZ0NBSUFEQVpnREFib0RDVUZOVXpNNk5qRXpOZUFEMERDSUJBQ1FCQUNZQkFIQkJBQUFBQUFBQUFBQXlRUUFBCQscQUFOZ0VBUEURlSxBQUFDSUJmY3ZxUVUBDQRBQQGoCDdFRgEKCQEMREJCUQkKAQEAeRUoAUwyKAAAWi4oALg0QVhBaEQzd0JhTEQzd0w0QmQyMG1nR0NCZ05WVTBTSUJnQ1FCZ0dZQmdDaEJnQQFONEFBQ1JBcUFZQnNnWWtDHXQARR0MAEcdDABJHQw8dUFZS5oClQEhSkJDNzJBajL1ASRuUEZiSUFRb0FEFfhUa1FEb0pRVTFUTXpvMk1UTTFRTkF3UxFRDFBBX1URDAxBQUFXHQwAWR0MAGEdDABjHQwQZUFDSkEdEMjYAvfpA-ACrZhI6gIwaHR0cHM6Ly90ZXN0Lm5leHgzNjAuaW8vYWRhcHRlci9uYXRpdmUJH_CaaHRtbIADAIgDAZADAJgDFKADAaoDAMAD4KgByAMA2AMA4AMA6AMA-AMDgAQAkgQJL29wZW5ydGIymAQAqAQAsgQMCAAQABgAIAAwADgAuAQAwASA2rgiyAQA0gQOOTMyNSNBTVMzOjYxMzXaBAIIAeAEAPAEvMm-LvoEEgkAAABAPG1IQBEAAACgV8oCQIgFAZgFAKAF______8BBbABqgUkM2MwMjkwYzEtNmU3NS00ZWY3LTllMzctMTdmNWViZjNiZmEzwAUAyQWJFxTwP9IFCQkJDHgAANgFAeAFAfAFmfQh-gUECAAQAJAGAZgGALgGAMEGCSUo8D_QBvUv2gYWChAJERkBAdpg4AYM8gYCCACABwGIBwCgB0HIB6b2BdIHDRVkASYI2gcGAV1oGADgBwDqBwIIAPAHAIoIAhAAlQgAAIA_mAgB&s=ccf63f2e483a37091d2475d895e7cf7c911d1a78&pp=${AUCTION_PRICE}', + }, + ], + }, + }, + }]; + expect(output).to.eql(expectOutput); + }); + }); + + describe('getUserSyncs()', () => { + const response = { body: { cookies: [] } }; + it('Verifies user sync without cookie in bid response', () => { + const syncs = spec.getUserSyncs({}, [response], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); + expect(syncs).to.eql([]); + }); + it('Verifies user sync with cookies in bid response', () => { + response.body.ext = { + cookies: [{ 'type': 'image', 'url': 'http://www.cookie.sync.org/' }] + }; + const syncs = spec.getUserSyncs({}, [response], DEFAULT_OPTIONS.gdprConsent); + const expectedSyncs = [{ type: 'image', url: 'http://www.cookie.sync.org/' }]; + expect(syncs).to.eql(expectedSyncs); + }); + it('Verifies user sync with no bid response', () => { + var syncs = spec.getUserSyncs({}, null, DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); + expect(syncs).to.eql([]); + }); + it('Verifies user sync with no bid body response', () => { + let syncs = spec.getUserSyncs({}, [], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); + expect(syncs).to.eql([]); + syncs = spec.getUserSyncs({}, [{}], DEFAULT_OPTIONS.gdprConsent, DEFAULT_OPTIONS.uspConsent); + expect(syncs).to.eql([]); + }); + }); +}); diff --git a/test/spec/modules/intentIqIdSystem_spec.js b/test/spec/modules/intentIqIdSystem_spec.js index 18dd0452943..756b9b0a628 100644 --- a/test/spec/modules/intentIqIdSystem_spec.js +++ b/test/spec/modules/intentIqIdSystem_spec.js @@ -13,7 +13,7 @@ import { storage, readData, storeData } from '../../../libraries/intentIqUtils/s import { gppDataHandler, uspDataHandler, gdprDataHandler } from '../../../src/consentHandler.js'; import { clearAllCookies } from '../../helpers/cookies.js'; import { detectBrowser, detectBrowserFromUserAgent, detectBrowserFromUserAgentData } from '../../../libraries/intentIqUtils/detectBrowserUtils.js'; -import {CLIENT_HINTS_KEY, FIRST_PARTY_KEY, PREBID, WITH_IIQ, WITHOUT_IIQ} from '../../../libraries/intentIqConstants/intentIqConstants.js'; +import { CLIENT_HINTS_KEY, FIRST_PARTY_KEY, PREBID, WITH_IIQ, WITHOUT_IIQ } from '../../../libraries/intentIqConstants/intentIqConstants.js'; import { decryptData } from '../../../libraries/intentIqUtils/cryptionUtils.js'; import { isCHSupported } from '../../../libraries/intentIqUtils/chUtils.js'; @@ -188,7 +188,7 @@ describe('IntentIQ tests', function () { it('should create global IIQ identity object', async () => { const globalName = `iiq_identity_${partner}` const callBackSpy = sinon.spy(); - const submoduleCallback = intentIqIdSubmodule.getId({ params: { partner }}).callback; + const submoduleCallback = intentIqIdSubmodule.getId({ params: { partner } }).callback; submoduleCallback(callBackSpy); await waitForClientHints() expect(window[globalName]).to.be.not.undefined @@ -197,7 +197,7 @@ describe('IntentIQ tests', function () { }) it('should not create a global IIQ identity object in case it was already created', () => { - intentIqIdSubmodule.getId({ params: { partner }}) + intentIqIdSubmodule.getId({ params: { partner } }) const secondTimeCalling = initializeGlobalIIQ(partner) expect(secondTimeCalling).to.be.false }) @@ -254,7 +254,7 @@ describe('IntentIQ tests', function () { const cookieValue = storage.getCookie('_iiq_fdata_' + partner); expect(cookieValue).to.not.equal(null); const decryptedData = JSON.parse(decryptData(JSON.parse(cookieValue).data)); - expect(decryptedData).to.deep.equal({eids: ['test_personid']}); + expect(decryptedData).to.deep.equal({ eids: ['test_personid'] }); }); it('should call the IntentIQ endpoint with only partner', async function () { @@ -280,10 +280,11 @@ describe('IntentIQ tests', function () { it('should send AT=20 request and send source in it', async function () { const usedBrowser = 'chrome'; - intentIqIdSubmodule.getId({params: { - partner: 10, - browserBlackList: usedBrowser - } + intentIqIdSubmodule.getId({ + params: { + partner: 10, + browserBlackList: usedBrowser + } }); const currentBrowserLowerCase = detectBrowser(); @@ -552,7 +553,7 @@ describe('IntentIQ tests', function () { JSON.stringify({ pid: 'test_pid', data: 'test_personid', ls: false }) ); expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.args[0][0]).to.deep.equal({eids: []}); + expect(callBackSpy.args[0][0]).to.deep.equal({ eids: [] }); }); it('send addition parameters if were found in localstorage', async function () { @@ -611,12 +612,13 @@ describe('IntentIQ tests', function () { it('should send AT=20 request and send spd in it', async function () { const spdValue = { foo: 'bar', value: 42 }; const encodedSpd = encodeURIComponent(JSON.stringify(spdValue)); - localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, JSON.stringify({pcid: '123', spd: spdValue})); + localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, JSON.stringify({ pcid: '123', spd: spdValue })); - intentIqIdSubmodule.getId({params: { - partner: 10, - browserBlackList: 'chrome' - } + intentIqIdSubmodule.getId({ + params: { + partner: 10, + browserBlackList: 'chrome' + } }); await waitForClientHints(); @@ -629,12 +631,13 @@ describe('IntentIQ tests', function () { it('should send AT=20 request and send spd string in it ', async function () { const spdValue = 'server provided data'; const encodedSpd = encodeURIComponent(spdValue); - localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, JSON.stringify({pcid: '123', spd: spdValue})); + localStorage.setItem(FIRST_PARTY_KEY + '_' + partner, JSON.stringify({ pcid: '123', spd: spdValue })); - intentIqIdSubmodule.getId({params: { - partner: 10, - browserBlackList: 'chrome' - } + intentIqIdSubmodule.getId({ + params: { + partner: 10, + browserBlackList: 'chrome' + } }); await waitForClientHints(); @@ -766,7 +769,7 @@ describe('IntentIQ tests', function () { storeData(FIRST_PARTY_KEY, JSON.stringify(FPD), allowedStorage, storage) const callBackSpy = sinon.spy() - const submoduleCallback = intentIqIdSubmodule.getId({...allConfigParams, params: {...allConfigParams.params, partner: newPartnerId}}).callback; + const submoduleCallback = intentIqIdSubmodule.getId({ ...allConfigParams, params: { ...allConfigParams.params, partner: newPartnerId } }).callback; submoduleCallback(callBackSpy); await waitForClientHints(); const request = server.requests[0]; @@ -787,7 +790,7 @@ describe('IntentIQ tests', function () { }; storeData(FIRST_PARTY_KEY, JSON.stringify(FPD), allowedStorage, storage) - const returnedObject = intentIqIdSubmodule.getId({...allConfigParams, params: {...allConfigParams.params, partner: newPartnerId}}); + const returnedObject = intentIqIdSubmodule.getId({ ...allConfigParams, params: { ...allConfigParams.params, partner: newPartnerId } }); await waitForClientHints(); expect(returnedObject.callback).to.be.undefined expect(server.requests.length).to.equal(0) // no server requests @@ -856,7 +859,7 @@ describe('IntentIQ tests', function () { const callBackSpy = sinon.spy(); const submoduleCallback = intentIqIdSubmodule.getId(defaultConfigParams).callback; - const data = {eids: {key1: 'value1', key2: 'value2'}} + const data = { eids: { key1: 'value1', key2: 'value2' } } submoduleCallback(callBackSpy); await waitForClientHints(); @@ -884,7 +887,7 @@ describe('IntentIQ tests', function () { it('should clear localStorage, update runtimeEids and trigger callback with empty data if isOptedOut is true in response', async function () { // Save some data to localStorage for FPD and CLIENT_HINTS const FIRST_PARTY_DATA_KEY = FIRST_PARTY_KEY + '_' + partner; - localStorage.setItem(FIRST_PARTY_DATA_KEY, JSON.stringify({terminationCause: 35, some_key: 'someValue'})); + localStorage.setItem(FIRST_PARTY_DATA_KEY, JSON.stringify({ terminationCause: 35, some_key: 'someValue' })); localStorage.setItem(CLIENT_HINTS_KEY, JSON.stringify({ hint: 'someClientHintData' })); mockConsentHandlers(uspData, gppData, gdprData); @@ -899,7 +902,7 @@ describe('IntentIQ tests', function () { request.respond( 200, responseHeader, - JSON.stringify({isOptedOut: true}) + JSON.stringify({ isOptedOut: true }) ); // Check that the URL contains the expected consent data @@ -928,7 +931,7 @@ describe('IntentIQ tests', function () { } }; const callBackSpy = sinon.spy(); - const submoduleCallback = intentIqIdSubmodule.getId({...customParams}).callback; + const submoduleCallback = intentIqIdSubmodule.getId({ ...customParams }).callback; submoduleCallback(callBackSpy); await waitForClientHints(); @@ -939,17 +942,21 @@ describe('IntentIQ tests', function () { it('should make request to correct address with iiqPixelServerAddress parameter', async function() { let wasCallbackCalled = false - const callbackConfigParams = { params: { partner: partner, - pai, - partnerClientIdType, - partnerClientId, - browserBlackList: 'Chrome', - iiqPixelServerAddress: syncTestAPILink, - callback: () => { - wasCallbackCalled = true - } } }; + const callbackConfigParams = { + params: { + partner: partner, + pai, + partnerClientIdType, + partnerClientId, + browserBlackList: 'Chrome', + iiqPixelServerAddress: syncTestAPILink, + callback: () => { + wasCallbackCalled = true + } + } + }; - intentIqIdSubmodule.getId({...callbackConfigParams}); + intentIqIdSubmodule.getId({ ...callbackConfigParams }); await waitForClientHints(); const request = server.requests[0]; @@ -1250,14 +1257,18 @@ describe('IntentIQ tests', function () { it('should run callback from params', async () => { let wasCallbackCalled = false - const callbackConfigParams = { params: { partner: partner, - pai, - partnerClientIdType, - partnerClientId, - browserBlackList: 'Chrome', - callback: () => { - wasCallbackCalled = true - } } }; + const callbackConfigParams = { + params: { + partner: partner, + pai, + partnerClientIdType, + partnerClientId, + browserBlackList: 'Chrome', + callback: () => { + wasCallbackCalled = true + } + } + }; await intentIqIdSubmodule.getId(callbackConfigParams); expect(wasCallbackCalled).to.equal(true); @@ -1278,7 +1289,7 @@ describe('IntentIQ tests', function () { it('should NOT send sourceMetaData and sourceMetaDataExternal in AT=39 if it is undefined', async function () { const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, sourceMetaData: undefined} }; + const configParams = { params: { ...allConfigParams.params, sourceMetaData: undefined } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() @@ -1291,7 +1302,7 @@ describe('IntentIQ tests', function () { it('should NOT send sourceMetaData in AT=39 if value is NAN', async function () { const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, sourceMetaData: NaN} }; + const configParams = { params: { ...allConfigParams.params, sourceMetaData: NaN } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() @@ -1303,7 +1314,7 @@ describe('IntentIQ tests', function () { it('should send sourceMetaData in AT=20 if it exists in configParams', async function () { const translatedMetaDataValue = translateMetadata(sourceMetaData) - const configParams = { params: {...allConfigParams.params, browserBlackList: 'chrome'} }; + const configParams = { params: { ...allConfigParams.params, browserBlackList: 'chrome' } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1314,7 +1325,7 @@ describe('IntentIQ tests', function () { }); it('should NOT send sourceMetaData in AT=20 if value is NAN', async function () { - const configParams = { params: {...allConfigParams.params, sourceMetaData: NaN, browserBlackList: 'chrome'} }; + const configParams = { params: { ...allConfigParams.params, sourceMetaData: NaN, browserBlackList: 'chrome' } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1327,7 +1338,7 @@ describe('IntentIQ tests', function () { it('should send pcid and idtype in AT=20 if it provided in config', async function () { const partnerClientId = 'partnerClientId 123'; const partnerClientIdType = 0; - const configParams = { params: {...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1341,7 +1352,7 @@ describe('IntentIQ tests', function () { it('should NOT send pcid and idtype in AT=20 if partnerClientId is NOT a string', async function () { const partnerClientId = 123; const partnerClientIdType = 0; - const configParams = { params: {...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1355,7 +1366,7 @@ describe('IntentIQ tests', function () { it('should NOT send pcid and idtype in AT=20 if partnerClientIdType is NOT a number', async function () { const partnerClientId = 'partnerClientId 123'; const partnerClientIdType = 'wrong'; - const configParams = { params: {...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, browserBlackList: 'chrome', partnerClientId, partnerClientIdType } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1370,7 +1381,7 @@ describe('IntentIQ tests', function () { const partnerClientId = 'partnerClientId 123'; const partnerClientIdType = 0; const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, partnerClientId, partnerClientIdType } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() @@ -1386,7 +1397,7 @@ describe('IntentIQ tests', function () { const partnerClientId = 123; const partnerClientIdType = 0; const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, partnerClientId, partnerClientIdType } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() @@ -1402,7 +1413,7 @@ describe('IntentIQ tests', function () { const partnerClientId = 'partnerClientId-123'; const partnerClientIdType = 'wrong'; const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, partnerClientId, partnerClientIdType} }; + const configParams = { params: { ...allConfigParams.params, partnerClientId, partnerClientIdType } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() @@ -1415,7 +1426,7 @@ describe('IntentIQ tests', function () { }); it('should NOT send sourceMetaData in AT=20 if sourceMetaDataExternal provided', async function () { - const configParams = { params: {...allConfigParams.params, browserBlackList: 'chrome', sourceMetaDataExternal: 123} }; + const configParams = { params: { ...allConfigParams.params, browserBlackList: 'chrome', sourceMetaDataExternal: 123 } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1426,7 +1437,7 @@ describe('IntentIQ tests', function () { }); it('should store first party data under the silo key when siloEnabled is true', async function () { - const configParams = { params: {...allConfigParams.params, siloEnabled: true} }; + const configParams = { params: { ...allConfigParams.params, siloEnabled: true } }; intentIqIdSubmodule.getId(configParams); await waitForClientHints() @@ -1441,7 +1452,7 @@ describe('IntentIQ tests', function () { it('should send siloEnabled value in the request', async function () { const callBackSpy = sinon.spy(); - const configParams = { params: {...allConfigParams.params, siloEnabled: true} }; + const configParams = { params: { ...allConfigParams.params, siloEnabled: true } }; const submoduleCallback = intentIqIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); await waitForClientHints() diff --git a/test/spec/modules/interactiveOffersBidAdapter_spec.js b/test/spec/modules/interactiveOffersBidAdapter_spec.js index 300e800bc0c..7283d8ceab2 100644 --- a/test/spec/modules/interactiveOffersBidAdapter_spec.js +++ b/test/spec/modules/interactiveOffersBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; -import {spec} from 'modules/interactiveOffersBidAdapter.js'; +import { spec } from 'modules/interactiveOffersBidAdapter.js'; describe('Interactive Offers Prebbid.js Adapter', function() { describe('isBidRequestValid function', function() { - const bid = {bidder: 'interactiveOffers', params: {partnerId: '100', tmax: 300}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}; + const bid = { bidder: 'interactiveOffers', params: { partnerId: '100', tmax: 300 }, mediaTypes: { banner: { sizes: [[300, 250]] } }, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0 }; it('returns true if all the required params are present and properly formatted', function() { expect(spec.isBidRequestValid(bid)).to.be.true; @@ -15,15 +15,15 @@ describe('Interactive Offers Prebbid.js Adapter', function() { }); it('returns false if any if the required params is not properly formatted', function() { - bid.params = {partnerid: '100', tmax: 250}; + bid.params = { partnerid: '100', tmax: 250 }; expect(spec.isBidRequestValid(bid)).to.be.false; - bid.params = {partnerId: '100', tmax: '+250'}; + bid.params = { partnerId: '100', tmax: '+250' }; expect(spec.isBidRequestValid(bid)).to.be.false; }); }); describe('buildRequests function', function() { - const validBidRequests = [{bidder: 'interactiveOffers', params: {partnerId: '100', tmax: 300}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}]; - const bidderRequest = {bidderCode: 'interactiveOffers', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', bidderRequestId: '1eb79bc9dd44a', bids: [{bidder: 'interactiveOffers', params: {partnerId: '100', tmax: 300}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], timeout: 5000, refererInfo: {referer: 'http://www.google.com', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://www.google.com'], canonicalUrl: null}}; + const validBidRequests = [{ bidder: 'interactiveOffers', params: { partnerId: '100', tmax: 300 }, mediaTypes: { banner: { sizes: [[300, 250]] } }, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0 }]; + const bidderRequest = { bidderCode: 'interactiveOffers', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', bidderRequestId: '1eb79bc9dd44a', bids: [{ bidder: 'interactiveOffers', params: { partnerId: '100', tmax: 300 }, mediaTypes: { banner: { sizes: [[300, 250]] } }, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0 }], timeout: 5000, refererInfo: { referer: 'http://www.google.com', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://www.google.com'], canonicalUrl: null } }; it('returns a Prebid.js request object with a valid json string at the "data" property', function() { const request = spec.buildRequests(validBidRequests, bidderRequest); @@ -31,8 +31,8 @@ describe('Interactive Offers Prebbid.js Adapter', function() { }); }); describe('interpretResponse function', function() { - const openRTBResponse = {body: [{cur: 'USD', id: '2052afa35febb79baa9893cc3ae8b83b89740df65fe98b1bd358dbae6e912801', seatbid: [{seat: 1493, bid: [{ext: {tagid: '227faa83f86546'}, crid: '24477', adm: '', nurl: '', adid: '1138', adomain: ['url.com'], price: '1.53', w: 300, h: 250, iurl: 'http://url.com', cat: ['IAB13-11'], id: '5507ced7a39c06942d3cb260197112ba712e4180', attr: [], impid: 1, cid: '13280'}]}], 'bidid': '0959b9d58ba71b3db3fa29dce3b117c01fc85de0'}], 'headers': {}}; - const prebidRequest = {method: 'POST', url: 'https://url.com', data: '{"id": "1aad860c-e04b-482b-acac-0da55ed491c8", "site": {"id": "url.com", "name": "url.com", "domain": "url.com", "page": "http://url.com", "ref": "http://url.com", "publisher": {"id": 100, "name": "http://url.com", "domain": "url.com"}, "content": {"language": "pt-PT"}}, "source": {"fd": 0, "tid": "1aad860c-e04b-482b-acac-0da55ed491c8", "pchain": ""}, "device": {"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36", "language": "pt-PT"}, "user": {}, "imp": [{"id":1, "secure": 0, "tagid": "227faa83f86546", "banner": {"pos": 0, "w": 300, "h": 250, "format": [{"w": 300, "h": 250}]}}], "tmax": 300}', bidderRequest: {bidderCode: 'interactiveOffers', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', bidderRequestId: '1eb79bc9dd44a', bids: [{bidder: 'interactiveOffers', params: {partnerId: '100', tmax: 300}, mediaTypes: {banner: {sizes: [[300, 250]]}}, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0}], timeout: 5000, refererInfo: {referer: 'http://url.com', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://url.com'], canonicalUrl: null}}}; + const openRTBResponse = { body: [{ cur: 'USD', id: '2052afa35febb79baa9893cc3ae8b83b89740df65fe98b1bd358dbae6e912801', seatbid: [{ seat: 1493, bid: [{ ext: { tagid: '227faa83f86546' }, crid: '24477', adm: '', nurl: '', adid: '1138', adomain: ['url.com'], price: '1.53', w: 300, h: 250, iurl: 'http://url.com', cat: ['IAB13-11'], id: '5507ced7a39c06942d3cb260197112ba712e4180', attr: [], impid: 1, cid: '13280' }] }], 'bidid': '0959b9d58ba71b3db3fa29dce3b117c01fc85de0' }], 'headers': {} }; + const prebidRequest = { method: 'POST', url: 'https://url.com', data: '{"id": "1aad860c-e04b-482b-acac-0da55ed491c8", "site": {"id": "url.com", "name": "url.com", "domain": "url.com", "page": "http://url.com", "ref": "http://url.com", "publisher": {"id": 100, "name": "http://url.com", "domain": "url.com"}, "content": {"language": "pt-PT"}}, "source": {"fd": 0, "tid": "1aad860c-e04b-482b-acac-0da55ed491c8", "pchain": ""}, "device": {"ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 11_2_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.192 Safari/537.36", "language": "pt-PT"}, "user": {}, "imp": [{"id":1, "secure": 0, "tagid": "227faa83f86546", "banner": {"pos": 0, "w": 300, "h": 250, "format": [{"w": 300, "h": 250}]}}], "tmax": 300}', bidderRequest: { bidderCode: 'interactiveOffers', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', bidderRequestId: '1eb79bc9dd44a', bids: [{ bidder: 'interactiveOffers', params: { partnerId: '100', tmax: 300 }, mediaTypes: { banner: { sizes: [[300, 250]] } }, adUnitCode: 'pageAd01', transactionId: '16526f30-3be2-43f6-ab37-f1ab1f2ac25d', sizes: [[300, 250]], bidId: '227faa83f86546', bidderRequestId: '1eb79bc9dd44a', auctionId: '1aad860c-e04b-482b-acac-0da55ed491c8', src: 'client', bidRequestsCount: 1, bidderRequestsCount: 1, bidderWinsCount: 0 }], timeout: 5000, refererInfo: { referer: 'http://url.com', reachedTop: true, isAmp: false, numIframes: 0, stack: ['http://url.com'], canonicalUrl: null } } }; it('returns an array of Prebid.js response objects', function() { const prebidResponses = spec.interpretResponse(openRTBResponse, prebidRequest); diff --git a/test/spec/modules/intersectionRtdProvider_spec.js b/test/spec/modules/intersectionRtdProvider_spec.js index d2885810b90..9fa934fd4f3 100644 --- a/test/spec/modules/intersectionRtdProvider_spec.js +++ b/test/spec/modules/intersectionRtdProvider_spec.js @@ -1,10 +1,10 @@ -import {config as _config, config} from 'src/config.js'; +import { config as _config, config } from 'src/config.js'; import { expect } from 'chai'; import * as events from 'src/events.js'; import * as prebidGlobal from 'src/prebidGlobal.js'; import { intersectionSubmodule } from 'modules/intersectionRtdProvider.js'; import * as utils from 'src/utils.js'; -import {getGlobal} from 'src/prebidGlobal.js'; +import { getGlobal } from 'src/prebidGlobal.js'; import 'src/prebid.js'; describe('Intersection RTD Provider', function () { @@ -15,7 +15,7 @@ describe('Intersection RTD Provider', function () { code: 'ad-slot-1', mediaTypes: { banner: { - sizes: [ [300, 250] ] + sizes: [[300, 250]] } }, bids: [ @@ -24,8 +24,8 @@ describe('Intersection RTD Provider', function () { } ] }; - const providerConfig = {name: 'intersection', waitForIt: true}; - const rtdConfig = {realTimeData: {auctionDelay: 200, dataProviders: [providerConfig]}} + const providerConfig = { name: 'intersection', waitForIt: true }; + const rtdConfig = { realTimeData: { auctionDelay: 200, dataProviders: [providerConfig] } } describe('IntersectionObserver not supported', function() { beforeEach(function() { sandbox = sinon.createSandbox(); @@ -60,9 +60,9 @@ describe('Intersection RTD Provider', function () { intersectionRatio: 1, isIntersecting: true, time: Date.now(), - boundingClientRect: {left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0}, - intersectionRect: {left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0}, - rootRect: {left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0} + boundingClientRect: { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0 }, + intersectionRect: { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0 }, + rootRect: { left: 0, top: 0, right: 0, bottom: 0, width: 0, height: 0, x: 0, y: 0 } } ]); }, @@ -85,7 +85,7 @@ describe('Intersection RTD Provider', function () { pbjs.addAdUnits([utils.deepClone(adUnit)]); config.setConfig(rtdConfig); const onDone = sandbox.stub(); - const requestBidObject = {adUnitCodes: [adUnit.code]}; + const requestBidObject = { adUnitCodes: [adUnit.code] }; intersectionSubmodule.init({}); intersectionSubmodule.getBidRequestData( requestBidObject, @@ -100,7 +100,7 @@ describe('Intersection RTD Provider', function () { it('should set intersection. (request with "adUnits")', function(done) { config.setConfig(rtdConfig); const onDone = sandbox.stub(); - const requestBidObject = {adUnits: [utils.deepClone(adUnit)]}; + const requestBidObject = { adUnits: [utils.deepClone(adUnit)] }; intersectionSubmodule.init(); intersectionSubmodule.getBidRequestData( requestBidObject, @@ -132,12 +132,12 @@ describe('Intersection RTD Provider', function () { config.setConfig(rtdConfig); remove(); const onDone = sandbox.stub(); - const requestBidObject = {adUnits: [utils.deepClone(adUnit)]}; + const requestBidObject = { adUnits: [utils.deepClone(adUnit)] }; intersectionSubmodule.init({}); intersectionSubmodule.getBidRequestData( requestBidObject, onDone, - {...providerConfig, test: 1} + { ...providerConfig, test: 1 } ); setTimeout(function() { sinon.assert.calledOnce(onDone); diff --git a/test/spec/modules/invamiaBidAdapter_spec.js b/test/spec/modules/invamiaBidAdapter_spec.js index 2f8f0612e44..7d9367931e0 100644 --- a/test/spec/modules/invamiaBidAdapter_spec.js +++ b/test/spec/modules/invamiaBidAdapter_spec.js @@ -1,12 +1,12 @@ -import {expect} from 'chai'; -import {spec} from 'modules/invamiaBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/invamiaBidAdapter.js'; describe('invamia bid adapter tests', function () { describe('bid requests', function () { it('should accept valid bid', function () { const validBid = { bidder: 'invamia', - params: {zoneId: 123}, + params: { zoneId: 123 }, }; expect(spec.isBidRequestValid(validBid)).to.equal(true); @@ -24,7 +24,7 @@ describe('invamia bid adapter tests', function () { it('should correctly build payload string', function () { const bidRequests = [{ bidder: 'invamia', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250]], @@ -46,7 +46,7 @@ describe('invamia bid adapter tests', function () { it('should support multiple bids', function () { const bidRequests = [{ bidder: 'invamia', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250]], @@ -58,7 +58,7 @@ describe('invamia bid adapter tests', function () { transactionId: '92489f71-1bf2-49a0-adf9-000cea934729', }, { bidder: 'invamia', - params: {zoneId: 321}, + params: { zoneId: 321 }, mediaTypes: { banner: { sizes: [[728, 90]], @@ -77,7 +77,7 @@ describe('invamia bid adapter tests', function () { it('should support multiple sizes', function () { const bidRequests = [{ bidder: 'invamia', - params: {zoneId: 123}, + params: { zoneId: 123 }, mediaTypes: { banner: { sizes: [[300, 250], [300, 600]], @@ -118,7 +118,7 @@ describe('invamia bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(1); expect(bids[0].requestId).to.equal('23acc48ad47af5'); @@ -144,7 +144,7 @@ describe('invamia bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(0); }); @@ -164,7 +164,7 @@ describe('invamia bid adapter tests', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest }); expect(bids).to.be.lengthOf(0); }); diff --git a/test/spec/modules/invibesBidAdapter_spec.js b/test/spec/modules/invibesBidAdapter_spec.js index c3c99788a70..66c5e3157ca 100644 --- a/test/spec/modules/invibesBidAdapter_spec.js +++ b/test/spec/modules/invibesBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { config } from 'src/config.js'; -import {spec, resetInvibes, stubDomainOptions, readGdprConsent, storage} from 'modules/invibesBidAdapter.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { spec, resetInvibes, stubDomainOptions, readGdprConsent, storage } from 'modules/invibesBidAdapter.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('invibesBidAdapter:', function () { const BIDDER_CODE = 'invibes'; @@ -250,7 +250,7 @@ describe('invibesBidAdapter:', function () { } } - top.window.invibes.bidResponse = {prop: 'prop'}; + top.window.invibes.bidResponse = { prop: 'prop' }; expect(spec.isBidRequestValid(validBid)).to.be.true; }); }); @@ -501,19 +501,19 @@ describe('invibesBidAdapter:', function () { }); it('sends query string params from localstorage 1', function () { - localStorage.ivbs = JSON.stringify({bvci: 1}); + localStorage.ivbs = JSON.stringify({ bvci: 1 }); const request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo); expect(request.data.bvci).to.equal(1); }); it('sends query string params from localstorage 2', function () { - localStorage.ivbs = JSON.stringify({invibbvlog: true}); + localStorage.ivbs = JSON.stringify({ invibbvlog: true }); const request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo); expect(request.data.invibbvlog).to.equal(true); }); it('does not send query string params from localstorage if unknwon', function () { - localStorage.ivbs = JSON.stringify({someparam: true}); + localStorage.ivbs = JSON.stringify({ someparam: true }); const request = spec.buildRequests(bidRequests, bidderRequestWithPageInfo); expect(request.data.someparam).to.be.undefined; }); @@ -620,7 +620,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -651,7 +651,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -682,7 +682,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -713,7 +713,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -768,7 +768,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -798,7 +798,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: false}}, + vendor: { consents: { 436: false } }, purpose: { consents: { 1: true, @@ -828,7 +828,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: false}, legitimateInterests: {436: true}}, + vendor: { consents: { 436: false }, legitimateInterests: { 436: true } }, purpose: { consents: { 1: true, @@ -858,7 +858,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: false}, legitimateInterests: {436: false}}, + vendor: { consents: { 436: false }, legitimateInterests: { 436: false } }, purpose: { consents: { 1: true, @@ -888,7 +888,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: false}}, + vendor: { consents: { 436: false } }, purpose: {} } }, @@ -906,7 +906,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -937,7 +937,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: true}}, + vendor: { consents: { 436: true } }, purpose: { consents: { 1: true, @@ -963,7 +963,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: null}, + vendor: { consents: null }, purpose: { consents: { 1: true, @@ -994,7 +994,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendor: {consents: {436: null}}, + vendor: { consents: { 436: null } }, purpose: { consents: { 1: true, @@ -1025,7 +1025,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendorConsents: {436: null}, + vendorConsents: { 436: null }, purposeConsents: { 1: true, 2: true, @@ -1089,7 +1089,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendorConsents: {436: true}, + vendorConsents: { 436: true }, purposeConsents: { 1: true, 2: true, @@ -1113,7 +1113,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendorConsents: {436: true}, + vendorConsents: { 436: true }, purposeConsents: { 1: false, 2: false, @@ -1137,7 +1137,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendorConsents: {436: true}, + vendorConsents: { 436: true }, purposeConsents: { 1: false, 2: false, @@ -1159,7 +1159,7 @@ describe('invibesBidAdapter:', function () { vendorData: { gdprApplies: true, hasGlobalConsent: false, - vendorConsents: {436: false}, + vendorConsents: { 436: false }, purposeConsents: { 1: true, 2: true, @@ -1310,47 +1310,47 @@ describe('invibesBidAdapter:', function () { context('when the response is not valid', function () { it('handles response with no bids requested', function () { - const emptyResult = spec.interpretResponse({body: response}); + const emptyResult = spec.interpretResponse({ body: response }); expect(emptyResult).to.be.empty; }); it('handles empty response', function () { - const emptyResult = spec.interpretResponse(null, {bidRequests}); + const emptyResult = spec.interpretResponse(null, { bidRequests }); expect(emptyResult).to.be.empty; }); it('handles response with bidding is not configured', function () { - const emptyResult = spec.interpretResponse({body: {Ads: [{BidPrice: 1}]}}, {bidRequests}); + const emptyResult = spec.interpretResponse({ body: { Ads: [{ BidPrice: 1 }] } }, { bidRequests }); expect(emptyResult).to.be.empty; }); it('handles response with no ads are received', function () { const emptyResult = spec.interpretResponse({ body: { - BidModel: {PlacementId: '12345'}, + BidModel: { PlacementId: '12345' }, AdReason: 'No ads' } - }, {bidRequests}); + }, { bidRequests }); expect(emptyResult).to.be.empty; }); it('handles response with no ads are received - no ad reason', function () { - const emptyResult = spec.interpretResponse({body: {BidModel: {PlacementId: '12345'}}}, {bidRequests}); + const emptyResult = spec.interpretResponse({ body: { BidModel: { PlacementId: '12345' } } }, { bidRequests }); expect(emptyResult).to.be.empty; }); it('handles response when no placement Id matches', function () { const emptyResult = spec.interpretResponse({ body: { - BidModel: {PlacementId: '123456'}, - Ads: [{BidPrice: 1}] + BidModel: { PlacementId: '123456' }, + Ads: [{ BidPrice: 1 }] } - }, {bidRequests}); + }, { bidRequests }); expect(emptyResult).to.be.empty; }); it('handles response when placement Id is not present', function () { - const emptyResult = spec.interpretResponse({BidModel: {}, Ads: [{BidPrice: 1}]}, {bidRequests}); + const emptyResult = spec.interpretResponse({ BidModel: {}, Ads: [{ BidPrice: 1 }] }, { bidRequests }); expect(emptyResult).to.be.empty; }); @@ -1362,30 +1362,30 @@ describe('invibesBidAdapter:', function () { context('when the multiresponse is valid', function () { it('responds with a valid multiresponse bid', function () { - const result = spec.interpretResponse({body: multiResponse}, {bidRequests}); + const result = spec.interpretResponse({ body: multiResponse }, { bidRequests }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('responds with a valid singleresponse bid', function () { - const result = spec.interpretResponse({body: response}, {bidRequests}); + const result = spec.interpretResponse({ body: response }, { bidRequests }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('does not make multiple bids', function () { - const result = spec.interpretResponse({body: response}, {bidRequests}); - const secondResult = spec.interpretResponse({body: response}, {bidRequests}); + const result = spec.interpretResponse({ body: response }, { bidRequests }); + const secondResult = spec.interpretResponse({ body: response }, { bidRequests }); expect(secondResult).to.be.empty; }); it('bids using the adUnitCode', function () { - const result = spec.interpretResponse({body: responseWithAdUnit}, {bidRequests}); + const result = spec.interpretResponse({ body: responseWithAdUnit }, { bidRequests }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); }); context('when the response has meta', function () { it('responds with a valid bid, with the meta info', function () { - const result = spec.interpretResponse({body: responseWithMeta}, {bidRequests}); + const result = spec.interpretResponse({ body: responseWithMeta }, { bidRequests }); expect(result[0].meta.advertiserName).to.equal('theadvertiser'); expect(result[0].meta.advertiserDomains).to.contain('theadvertiser.com'); expect(result[0].meta.advertiserDomains).to.contain('theadvertiser_2.com'); @@ -1396,14 +1396,14 @@ describe('invibesBidAdapter:', function () { it('works when no LID is not sent from AdWeb', function() { var firstResponse = buildResponse('12345', 1, [], 123); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); expect(firstResult[0].creativeId).to.equal(123); }); it('sets lid when AdWeb sends it', function() { var firstResponse = buildResponse('12345', 1, [], 123, true); - spec.interpretResponse({body: firstResponse}, {bidRequests}); + spec.interpretResponse({ body: firstResponse }, { bidRequests }); expect(global.document.cookie.indexOf('ivbsdid')).to.greaterThanOrEqual(0); }); }); @@ -1413,8 +1413,8 @@ describe('invibesBidAdapter:', function () { var firstResponse = buildResponse('12345', 1, [1], 123); var secondResponse = buildResponse('abcde', 2, [2], 456); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); - var secondResult = spec.interpretResponse({body: secondResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); + var secondResult = spec.interpretResponse({ body: secondResponse }, { bidRequests }); expect(secondResult[0].creativeId).to.equal(456); }); @@ -1422,8 +1422,8 @@ describe('invibesBidAdapter:', function () { var firstResponse = buildResponse('12345', 1, [], 123); var secondResponse = buildResponse('abcde', 2, [], 456); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); - var secondResult = spec.interpretResponse({body: secondResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); + var secondResult = spec.interpretResponse({ body: secondResponse }, { bidRequests }); expect(secondResult[0].creativeId).to.equal(456); }); @@ -1431,8 +1431,8 @@ describe('invibesBidAdapter:', function () { var firstResponse = buildResponse('12345', 1, [2], 123); var secondResponse = buildResponse('abcde', 2, [], 456); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); - var secondResult = spec.interpretResponse({body: secondResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); + var secondResult = spec.interpretResponse({ body: secondResponse }, { bidRequests }); expect(secondResult).to.be.empty; }); @@ -1440,8 +1440,8 @@ describe('invibesBidAdapter:', function () { var firstResponse = buildResponse('12345', 1, [], 123); var secondResponse = buildResponse('abcde', 2, [1], 456); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); - var secondResult = spec.interpretResponse({body: secondResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); + var secondResult = spec.interpretResponse({ body: secondResponse }, { bidRequests }); expect(secondResult).to.be.empty; }); @@ -1449,8 +1449,8 @@ describe('invibesBidAdapter:', function () { var firstResponse = buildResponse('12345', 1, [1], 123); var secondResponse = buildResponse('abcde', 1, [1], 456); - var firstResult = spec.interpretResponse({body: firstResponse}, {bidRequests}); - var secondResult = spec.interpretResponse({body: secondResponse}, {bidRequests}); + var firstResult = spec.interpretResponse({ body: firstResponse }, { bidRequests }); + var secondResult = spec.interpretResponse({ body: secondResponse }, { bidRequests }); expect(secondResult).to.be.empty; }); }); @@ -1459,14 +1459,14 @@ describe('invibesBidAdapter:', function () { describe('getUserSyncs', function () { it('returns undefined if disableUserSyncs not passed as bid request param ', function () { spec.buildRequests(bidRequestsWithUserId, bidderRequestWithPageInfo); - const response = spec.getUserSyncs({iframeEnabled: true}); + const response = spec.getUserSyncs({ iframeEnabled: true }); expect(response).to.equal(undefined); }); it('returns an iframe if enabled', function () { spec.buildRequests(bidRequests, bidderRequestWithPageInfo); - const response = spec.getUserSyncs({iframeEnabled: true}); + const response = spec.getUserSyncs({ iframeEnabled: true }); expect(response.type).to.equal('iframe'); expect(response.url).to.include(SYNC_ENDPOINT); }); @@ -1475,7 +1475,7 @@ describe('invibesBidAdapter:', function () { top.window.invibes.optIn = 1; spec.buildRequests(bidRequests, bidderRequestWithPageInfo); - const response = spec.getUserSyncs({iframeEnabled: true}); + const response = spec.getUserSyncs({ iframeEnabled: true }); expect(response.type).to.equal('iframe'); expect(response.url).to.include(SYNC_ENDPOINT); expect(response.url).to.include('optIn'); @@ -1488,7 +1488,7 @@ describe('invibesBidAdapter:', function () { global.document.cookie = 'ivbsdid={"id":"dvdjkams6nkq","cr":' + Date.now() + ',"hc":0}'; SetBidderAccess(); - const response = spec.getUserSyncs({iframeEnabled: true}); + const response = spec.getUserSyncs({ iframeEnabled: true }); expect(response.type).to.equal('iframe'); expect(response.url).to.include(SYNC_ENDPOINT); expect(response.url).to.include('optIn'); @@ -1502,7 +1502,7 @@ describe('invibesBidAdapter:', function () { localStorage.ivbsdid = 'dvdjkams6nkq'; SetBidderAccess(); - const response = spec.getUserSyncs({iframeEnabled: true}); + const response = spec.getUserSyncs({ iframeEnabled: true }); expect(response.type).to.equal('iframe'); expect(response.url).to.include(SYNC_ENDPOINT); expect(response.url).to.include('optIn'); @@ -1512,7 +1512,7 @@ describe('invibesBidAdapter:', function () { it('returns undefined if iframe not enabled ', function () { spec.buildRequests(bidRequests, bidderRequestWithPageInfo); - const response = spec.getUserSyncs({iframeEnabled: false}); + const response = spec.getUserSyncs({ iframeEnabled: false }); expect(response).to.equal(undefined); }); diff --git a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js index 71182d146a0..b4e6dd8629b 100644 --- a/test/spec/modules/invisiblyAnalyticsAdapter_spec.js +++ b/test/spec/modules/invisiblyAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import invisiblyAdapter from 'modules/invisiblyAnalyticsAdapter.js'; import { expect } from 'chai'; -import {expectEvents} from '../../helpers/analytics.js'; -import {server} from '../../mocks/xhr.js'; +import { expectEvents } from '../../helpers/analytics.js'; +import { server } from '../../mocks/xhr.js'; import { EVENTS, STATUS } from 'src/constants.js'; const events = require('src/events'); diff --git a/test/spec/modules/ipromBidAdapter_spec.js b/test/spec/modules/ipromBidAdapter_spec.js index 3a1a6c972e1..3766499b0e6 100644 --- a/test/spec/modules/ipromBidAdapter_spec.js +++ b/test/spec/modules/ipromBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/ipromBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/ipromBidAdapter.js'; describe('iPROM Adapter', function () { let bidRequests; @@ -169,7 +169,8 @@ describe('iPROM Adapter', function () { ad: 'Iprom Header bidding example', aDomains: ['https://example.com'], } - ]}; + ] + }; const request = spec.buildRequests(bidRequests, bidderRequest); const bids = spec.interpretResponse(serverResponse, request); diff --git a/test/spec/modules/iqxBidAdapter_spec.js b/test/spec/modules/iqxBidAdapter_spec.js index 8ca6fce841c..16d0b74e689 100644 --- a/test/spec/modules/iqxBidAdapter_spec.js +++ b/test/spec/modules/iqxBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/iqxBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/iqxBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; const ENDPOINT = 'https://pbjs.iqzonertb.live'; @@ -99,7 +99,7 @@ describe('iqxBidAdapter', () => { expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); expect(request).to.have.property('floor').and.to.equal(null); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -192,7 +192,7 @@ describe('iqxBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -208,8 +208,8 @@ describe('iqxBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -261,7 +261,7 @@ describe('iqxBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -270,7 +270,7 @@ describe('iqxBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['iqx']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['iqx'] }); }); it('should interpret valid banner response', function () { @@ -291,7 +291,7 @@ describe('iqxBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -317,7 +317,7 @@ describe('iqxBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequestVideo}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequestVideo }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -333,12 +333,12 @@ describe('iqxBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -357,7 +357,7 @@ describe('iqxBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -376,7 +376,7 @@ describe('iqxBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -400,20 +400,20 @@ describe('iqxBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -421,7 +421,7 @@ describe('iqxBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -429,7 +429,7 @@ describe('iqxBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/iqzoneBidAdapter_spec.js b/test/spec/modules/iqzoneBidAdapter_spec.js index c14b85b2c8b..7f48b7077bf 100644 --- a/test/spec/modules/iqzoneBidAdapter_spec.js +++ b/test/spec/modules/iqzoneBidAdapter_spec.js @@ -480,7 +480,7 @@ describe('IQZoneBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -489,9 +489,7 @@ describe('IQZoneBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.iqzone.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -500,7 +498,7 @@ describe('IQZoneBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.iqzone.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/ixBidAdapter_spec.js b/test/spec/modules/ixBidAdapter_spec.js index eb352fa4ebe..d6a5d624547 100644 --- a/test/spec/modules/ixBidAdapter_spec.js +++ b/test/spec/modules/ixBidAdapter_spec.js @@ -553,7 +553,7 @@ describe('IndexexchangeAdapter', function () { } }, nativeOrtbRequest: { - assets: [{id: 0, required: 0, img: {type: 1}}, {id: 1, required: 1, title: {len: 140}}, {id: 2, required: 1, data: {type: 2}}, {id: 3, required: 1, img: {type: 3}}, {id: 4, required: false, video: {mimes: ['video/mp4', 'video/webm'], minduration: 0, maxduration: 120, protocols: [2, 3, 5, 6]}}] + assets: [{ id: 0, required: 0, img: { type: 1 } }, { id: 1, required: 1, title: { len: 140 } }, { id: 2, required: 1, data: { type: 2 } }, { id: 3, required: 1, img: { type: 3 } }, { id: 4, required: false, video: { mimes: ['video/mp4', 'video/webm'], minduration: 0, maxduration: 120, protocols: [2, 3, 5, 6] } }] }, adUnitCode: 'div-gpt-ad-1460505748562-0', transactionId: '273f49a8-7549-4218-a23c-e7ba59b47230', @@ -958,7 +958,7 @@ describe('IndexexchangeAdapter', function () { '33acrossId': { envelope: 'v1.5fs.1000.fjdiosmclds' }, 'criteoID': { envelope: 'testcriteoID' }, 'euidID': { envelope: 'testeuid' }, - pairId: {envelope: 'testpairId'} + pairId: { envelope: 'testpairId' } }; const DEFAULT_USERID_PAYLOAD = [ @@ -1978,12 +1978,15 @@ describe('IndexexchangeAdapter', function () { dsaparams: [1] }] } - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: { - ext: { - dsa: deepClone(dsa) + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { + ortb2: { + regs: { + ext: { + dsa: deepClone(dsa) + } + } } - } - }})[0]; + })[0]; const r = extractPayload(request); expect(r.regs.ext.dsa.dsarequired).to.equal(dsa.dsarequired); @@ -1999,12 +2002,15 @@ describe('IndexexchangeAdapter', function () { datatopub: '2', transparency: 20 } - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: { - ext: { - dsa: deepClone(dsa) + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { + ortb2: { + regs: { + ext: { + dsa: deepClone(dsa) + } + } } - } - }})[0]; + })[0]; const r = extractPayload(request); expect(r.regs).to.be.undefined; @@ -2024,18 +2030,21 @@ describe('IndexexchangeAdapter', function () { dsaparams: ['1'] }] } - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: { - ext: { - dsa: deepClone(dsa) + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { + ortb2: { + regs: { + ext: { + dsa: deepClone(dsa) + } + } } - } - }})[0]; + })[0]; const r = extractPayload(request); expect(r.regs).to.be.undefined; }); it('should set gpp and gpp_sid field when defined', function () { - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: {gpp: 'gpp', gpp_sid: [1]}} })[0]; + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: { regs: { gpp: 'gpp', gpp_sid: [1] } } })[0]; const r = extractPayload(request); expect(r.regs.gpp).to.equal('gpp'); @@ -2043,13 +2052,13 @@ describe('IndexexchangeAdapter', function () { expect(r.regs.gpp_sid).to.include(1); }); it('should not set gpp, gpp_sid and dsa field when not defined', function () { - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: {}} })[0]; + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: { regs: {} } })[0]; const r = extractPayload(request); expect(r.regs).to.be.undefined; }); it('should not set gpp and gpp_sid field when fields arent strings or array defined', function () { - const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: {regs: {gpp: 1, gpp_sid: 'string'}} })[0]; + const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2: { regs: { gpp: 1, gpp_sid: 'string' } } })[0]; const r = extractPayload(request); expect(r.regs).to.be.undefined; @@ -2550,22 +2559,23 @@ describe('IndexexchangeAdapter', function () { sua: { platform: { brand: 'macOS', - version: [ '12', '6', '1' ] + version: ['12', '6', '1'] }, browsers: [ { brand: 'Chromium', - version: [ '107', '0', '5249', '119' ] + version: ['107', '0', '5249', '119'] }, { brand: 'Google Chrome', - version: [ '107', '0', '5249', '119' ] + version: ['107', '0', '5249', '119'] }, ], mobile: 0, model: '' } - }}; + } + }; const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2 })[0]; const payload = extractPayload(request); @@ -2574,8 +2584,7 @@ describe('IndexexchangeAdapter', function () { }); it('should not set device sua if not available in fpd', function () { - const ortb2 = { - device: {}}; + const ortb2 = { device: {} }; const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2 })[0]; const payload = extractPayload(request); @@ -4355,7 +4364,7 @@ describe('IndexexchangeAdapter', function () { beforeEach(() => { bidderRequestWithFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID_WITH_FLEDGE_ENABLED, {})[0]; - bidderRequestWithFledgeEnabled.paapi = {enabled: true}; + bidderRequestWithFledgeEnabled.paapi = { enabled: true }; serverResponseWithoutFledgeConfigs = { body: { @@ -4460,7 +4469,7 @@ describe('IndexexchangeAdapter', function () { }; bidderRequestWithFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID_WITH_FLEDGE_ENABLED, {})[0]; - bidderRequestWithFledgeEnabled.paapi = {enabled: true}; + bidderRequestWithFledgeEnabled.paapi = { enabled: true }; bidderRequestWithoutFledgeEnabled = spec.buildRequests(DEFAULT_BANNER_VALID_BID, {})[0]; }); @@ -5390,7 +5399,8 @@ describe('IndexexchangeAdapter', function () { device: { ip: '192.168.1.1', ipv6: '2001:0db8:85a3:0000:0000:8a2e:0370:7334' - }}; + } + }; const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2 })[0]; const payload = extractPayload(request); expect(payload.device.ip).to.equal('192.168.1.1') @@ -5398,7 +5408,7 @@ describe('IndexexchangeAdapter', function () { }); it('should not add device.ip if neither ip nor ipv6 exists', () => { - const ortb2 = {device: {}}; + const ortb2 = { device: {} }; const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2 })[0]; const payload = extractPayload(request); expect(payload.device.ip).to.be.undefined; @@ -5425,7 +5435,7 @@ describe('IndexexchangeAdapter', function () { }); it('should not add device.geo if it does not exist', () => { - const ortb2 = {device: {}}; + const ortb2 = { device: {} }; const request = spec.buildRequests(DEFAULT_BANNER_VALID_BID, { ortb2 })[0]; const payload = extractPayload(request); expect(payload.device.geo).to.be.undefined; @@ -5444,7 +5454,7 @@ describe('IndexexchangeAdapter', function () { it('retrieves divId from GPT once and caches result', () => { const adUnitCode = 'div-ad2'; - const stub = sinon.stub(gptUtils, 'getGptSlotInfoForAdUnitCode').returns({divId: 'gpt-div'}); + const stub = sinon.stub(gptUtils, 'getGptSlotInfoForAdUnitCode').returns({ divId: 'gpt-div' }); const first = getDivIdFromAdUnitCode(adUnitCode); const second = getDivIdFromAdUnitCode(adUnitCode); expect(first).to.equal('gpt-div'); diff --git a/test/spec/modules/jixieBidAdapter_spec.js b/test/spec/modules/jixieBidAdapter_spec.js index bd56aee71a6..fb904e4b12b 100644 --- a/test/spec/modules/jixieBidAdapter_spec.js +++ b/test/spec/modules/jixieBidAdapter_spec.js @@ -89,7 +89,7 @@ describe('jixie Adapter', function () { // to serve as the object that prebid will call jixie buildRequest with: (param2) const bidderRequest_ = { - refererInfo: {referer: pageurl_}, + refererInfo: { referer: pageurl_ }, auctionId: auctionId_, timeout: timeout_ }; @@ -344,7 +344,7 @@ describe('jixie Adapter', function () { it('it should popular the device info when it is available', function () { const getConfigStub = sinon.stub(config, 'getConfig'); - const content = {w: 500, h: 400}; + const content = { w: 500, h: 400 }; getConfigStub.callsFake(function fakeFn(prop) { if (prop === 'device') { return content; @@ -617,14 +617,14 @@ describe('jixie Adapter', function () { describe('interpretResponse', function () { it('handles nobid responses', function () { - expect(spec.interpretResponse({body: {}}, {validBidRequests: []}).length).to.equal(0) - expect(spec.interpretResponse({body: []}, {validBidRequests: []}).length).to.equal(0) + expect(spec.interpretResponse({ body: {} }, { validBidRequests: [] }).length).to.equal(0) + expect(spec.interpretResponse({ body: [] }, { validBidRequests: [] }).length).to.equal(0) }); it('should get correct bid response', function () { const setCookieSpy = sinon.spy(storage, 'setCookie'); const setLocalStorageSpy = sinon.spy(storage, 'setDataInLocalStorage'); - const result = spec.interpretResponse({body: responseBody_}, requestObj_) + const result = spec.interpretResponse({ body: responseBody_ }, requestObj_) expect(setLocalStorageSpy.calledWith('_jxx', '43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); expect(setLocalStorageSpy.calledWith('_jxxs', '1600057934-43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); expect(setCookieSpy.calledWith('_jxxs', '1600057934-43aacc10-f643-11ea-8a10-c5fe2d394e7e')).to.equal(true); diff --git a/test/spec/modules/jixieIdSystem_spec.js b/test/spec/modules/jixieIdSystem_spec.js index 14559bff174..eb95b59b02c 100644 --- a/test/spec/modules/jixieIdSystem_spec.js +++ b/test/spec/modules/jixieIdSystem_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { jixieIdSubmodule, storage } from 'modules/jixieIdSystem.js'; import { server } from '../../mocks/xhr.js'; -import {parseUrl} from '../../../src/utils.js'; +import { parseUrl } from '../../../src/utils.js'; const COOKIE_EXPIRATION_FUTURE = (new Date(Date.now() + 60 * 60 * 24 * 1000)).toUTCString(); const COOKIE_EXPIRATION_PAST = (new Date(Date.now() - 60 * 60 * 24 * 1000)).toUTCString(); @@ -54,8 +54,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -76,8 +76,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -98,8 +98,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -126,8 +126,8 @@ describe('JixieId Submodule', () => { params: { accountid: ACCOUNTID, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -161,8 +161,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -200,8 +200,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }); @@ -217,7 +217,7 @@ describe('JixieId Submodule', () => { }); context('when has rather stale pbjs jixie cookie', () => { it('should call the server and set the id; send available extra info (e.g. esha,psha, consent if available)', () => { - const consentData = {gdpr: {gdprApplies: 1, consentString: MOCK_CONSENT_STRING}}; + const consentData = { gdpr: { gdprApplies: 1, consentString: MOCK_CONSENT_STRING } }; storage.setCookie(PBJS_JXID_KEY, CLIENTID1, COOKIE_EXPIRATION_FUTURE) storage.setCookie(PBJS_IDLOGSTR_KEY, IDLOG_EXPIRED, COOKIE_EXPIRATION_FUTURE) storage.setCookie(EID_TYPE1_COOKIENAME, EID_TYPE1_SAMPLEVALUE, COOKIE_EXPIRATION_FUTURE) @@ -229,8 +229,8 @@ describe('JixieId Submodule', () => { params: { stdjxidckname: STD_JXID_KEY, pubExtIds: [ - {pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME}, - {pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME} + { pname: EID_TYPE1_PARAMNAME, ckname: EID_TYPE1_COOKIENAME }, + { pname: EID_TYPE2_PARAMNAME, lsname: EID_TYPE2_LSNAME } ] } }, consentData); diff --git a/test/spec/modules/justIdSystem_spec.js b/test/spec/modules/justIdSystem_spec.js index 4a5ebb35b0a..b2eaa14132d 100644 --- a/test/spec/modules/justIdSystem_spec.js +++ b/test/spec/modules/justIdSystem_spec.js @@ -29,7 +29,7 @@ describe('JustIdSystem', function () { describe('decode', function() { it('decode justId', function() { const justId = 'aaa'; - expect(justIdSubmodule.decode({uid: justId})).to.deep.eq({justId: justId}); + expect(justIdSubmodule.decode({ uid: justId })).to.deep.eq({ justId: justId }); }) }); @@ -75,7 +75,7 @@ describe('JustIdSystem', function () { const atmVarName = '__fakeAtm'; - justIdSubmodule.getId({params: {atmVarName: atmVarName}}).callback(callbackSpy); + justIdSubmodule.getId({ params: { atmVarName: atmVarName } }).callback(callbackSpy); expect(getAtmStub.lastCall.lastArg).to.equal(atmVarName); }); @@ -106,7 +106,7 @@ describe('JustIdSystem', function () { it('work with stub', function(done) { var calls = []; currentAtm = (cmd, param) => { - calls.push({cmd: cmd, param: param}); + calls.push({ cmd: cmd, param: param }); } const callbackSpy = sinon.stub(); @@ -190,7 +190,7 @@ describe('JustIdSystem', function () { const b = { y: 'y' } const c = { z: 'z' } - justIdSubmodule.getId(a, {gdpr: b}, c).callback(callbackSpy); + justIdSubmodule.getId(a, { gdpr: b }, c).callback(callbackSpy); scriptTagCallback(); diff --git a/test/spec/modules/justpremiumBidAdapter_spec.js b/test/spec/modules/justpremiumBidAdapter_spec.js index 21cd488e745..bb09e83f514 100644 --- a/test/spec/modules/justpremiumBidAdapter_spec.js +++ b/test/spec/modules/justpremiumBidAdapter_spec.js @@ -95,7 +95,7 @@ describe('justpremium adapter', function () { }) it('Verify build request', function () { - expect(spec.isBidRequestValid({bidder: 'justpremium', params: {}})).to.equal(false) + expect(spec.isBidRequestValid({ bidder: 'justpremium', params: {} })).to.equal(false) expect(spec.isBidRequestValid({})).to.equal(false) expect(spec.isBidRequestValid(adUnits[0])).to.equal(true) expect(spec.isBidRequestValid(adUnits[1])).to.equal(true) @@ -176,7 +176,7 @@ describe('justpremium adapter', function () { } ] - const result = spec.interpretResponse({body: response}, request) + const result = spec.interpretResponse({ body: response }, request) expect(Object.keys(result[0])).to.deep.equal(Object.keys(expectedResponse[0])) expect(result[0]).to.not.equal(null) @@ -190,7 +190,7 @@ describe('justpremium adapter', function () { expect(result[0].netRevenue).to.equal(true) expect(result[0].format).to.equal('lb') expect(result[0].meta.advertiserDomains[0]).to.equal('justpremium.com') - expect(result[0].adserverTargeting).to.deep.equal({'hb_deal_justpremium': 'jp_pg'}) + expect(result[0].adserverTargeting).to.deep.equal({ 'hb_deal_justpremium': 'jp_pg' }) }) it('Verify wrong server response', function () { @@ -203,14 +203,14 @@ describe('justpremium adapter', function () { } } - const result = spec.interpretResponse({body: response}, request) + const result = spec.interpretResponse({ body: response }, request) expect(result.length).to.equal(0) }) }) describe('getUserSyncs', function () { it('Verifies sync options for iframe', function () { - const options = spec.getUserSyncs({iframeEnabled: true}, {}, {gdprApplies: true, consentString: 'BOOgjO9OOgjO9APABAENAi-AAAAWd'}, '1YYN') + const options = spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'BOOgjO9OOgjO9APABAENAi-AAAAWd' }, '1YYN') expect(options).to.not.be.undefined expect(options[0].type).to.equal('iframe') expect(options[0].url).to.match(/\/\/pre.ads.justpremium.com\/v\/1.0\/t\/sync/) @@ -218,7 +218,7 @@ describe('justpremium adapter', function () { expect(options[0].url).to.match(/&usPrivacy=1YYN/) }) it('Returns array of user sync pixels', function () { - const options = spec.getUserSyncs({pixelEnabled: true}, serverResponses) + const options = spec.getUserSyncs({ pixelEnabled: true }, serverResponses) expect(options).to.not.be.undefined expect(Array.isArray(options)).to.be.true expect(options[0].type).to.equal('image') diff --git a/test/spec/modules/jwplayerBidAdapter_spec.js b/test/spec/modules/jwplayerBidAdapter_spec.js index ae456919238..4469f4cbfad 100644 --- a/test/spec/modules/jwplayerBidAdapter_spec.js +++ b/test/spec/modules/jwplayerBidAdapter_spec.js @@ -71,19 +71,19 @@ describe('jwplayerBidAdapter', function() { }); it('should be invalid when the bid request only includes a publisher ID', function() { - assert(spec.isBidRequestValid({params: {publisherId: 'foo'}}) === false); + assert(spec.isBidRequestValid({ params: { publisherId: 'foo' } }) === false); }); it('should be invalid when the bid request only includes a placement ID', function() { - assert(spec.isBidRequestValid({params: {placementId: 'foo'}}) === false); + assert(spec.isBidRequestValid({ params: { placementId: 'foo' } }) === false); }); it('should be invalid when the bid request only includes a site ID', function() { - assert(spec.isBidRequestValid({params: {siteId: 'foo'}}) === false); + assert(spec.isBidRequestValid({ params: { siteId: 'foo' } }) === false); }); it('should be valid when the bid includes a placement ID, a publisher ID and a site ID', function() { - assert(spec.isBidRequestValid({params: {placementId: 'foo', publisherId: 'bar', siteId: 'siteId '}}) === true); + assert(spec.isBidRequestValid({ params: { placementId: 'foo', publisherId: 'bar', siteId: 'siteId ' } }) === true); }); }); diff --git a/test/spec/modules/jwplayerRtdProvider_spec.js b/test/spec/modules/jwplayerRtdProvider_spec.js index e60d346de0f..c639f37e9dd 100644 --- a/test/spec/modules/jwplayerRtdProvider_spec.js +++ b/test/spec/modules/jwplayerRtdProvider_spec.js @@ -15,14 +15,14 @@ import { getPlayer, jwplayerSubmodule } from 'modules/jwplayerRtdProvider.js'; -import {server} from 'test/mocks/xhr.js'; -import {deepClone} from '../../../src/utils.js'; +import { server } from 'test/mocks/xhr.js'; +import { deepClone } from '../../../src/utils.js'; describe('jwplayerRtdProvider', function() { const testIdForSuccess = 'test_id_for_success'; const testIdForFailure = 'test_id_for_failure'; const validSegments = ['test_seg_1', 'test_seg_2']; - const responseHeader = {'Content-Type': 'application/json'}; + const responseHeader = { 'Content-Type': 'application/json' }; describe('Fetch targeting for mediaID tests', function () { let request; @@ -527,7 +527,7 @@ describe('jwplayerRtdProvider', function() { bids }; - const ortb2Fragments = {global: {}}; + const ortb2Fragments = { global: {} }; enrichAdUnits([adUnit], ortb2Fragments); const bid1 = bids[0]; const bid2 = bids[1]; @@ -597,13 +597,13 @@ describe('jwplayerRtdProvider', function() { id: 'randomContentId', data: [{ name: 'random', - segment: [{id: 'random'}] + segment: [{ id: 'random' }] }, { name: 'jwplayer.com', - segment: [{id: 'randomJwPlayer'}] + segment: [{ id: 'randomJwPlayer' }] }, { name: 'random2', - segment: [{id: 'random2'}] + segment: [{ id: 'random2' }] }] } } @@ -637,11 +637,11 @@ describe('jwplayerRtdProvider', function() { const randomDatum = data[0]; expect(randomDatum).to.have.property('name', 'random'); - expect(randomDatum.segment).to.deep.equal([{id: 'random'}]); + expect(randomDatum.segment).to.deep.equal([{ id: 'random' }]); const randomDatum2 = data[1]; expect(randomDatum2).to.have.property('name', 'random2'); - expect(randomDatum2.segment).to.deep.equal([{id: 'random2'}]); + expect(randomDatum2.segment).to.deep.equal([{ id: 'random2' }]); const jwplayerDatum = data[2]; expect(jwplayerDatum).to.have.property('name', 'jwplayer.com'); @@ -1531,10 +1531,10 @@ describe('jwplayerRtdProvider', function() { }); describe('Add Targeting to Bid', function () { - const targeting = {foo: 'bar'}; + const targeting = { foo: 'bar' }; it('creates realTimeData when absent from Bid', function () { - const targeting = {foo: 'bar'}; + const targeting = { foo: 'bar' }; const bid = {}; addTargetingToBid(bid, targeting); expect(bid).to.have.property('rtd'); @@ -1804,7 +1804,7 @@ describe('jwplayerRtdProvider', function() { } } }, - bids: [ bid ] + bids: [bid] }; const expectedContentId = 'jw_' + adUnit.ortb2Imp.ext.data.jwTargeting.mediaID; const expectedTargeting = { @@ -1813,7 +1813,7 @@ describe('jwplayerRtdProvider', function() { } }; - jwplayerSubmodule.getBidRequestData({ adUnits: [ adUnit ] }, bidRequestSpy); + jwplayerSubmodule.getBidRequestData({ adUnits: [adUnit] }, bidRequestSpy); expect(bidRequestSpy.calledOnce).to.be.true; expect(bid.rtd.jwplayer.targeting).to.not.have.property('segments'); expect(bid.rtd.jwplayer.targeting).to.not.have.property('segments'); @@ -1828,11 +1828,11 @@ describe('jwplayerRtdProvider', function() { const adUnitWithMediaId = { code: adUnitCode, mediaID: testIdForSuccess, - bids: [ bid1 ] + bids: [bid1] }; const adUnitEmpty = { code: 'test_ad_unit_empty', - bids: [ bid2 ] + bids: [bid2] }; const adUnitEmptyfpd = { @@ -1842,7 +1842,7 @@ describe('jwplayerRtdProvider', function() { id: 'sthg' } }, - bids: [ bid3 ] + bids: [bid3] }; jwplayerSubmodule.getBidRequestData({ adUnits: [adUnitWithMediaId, adUnitEmpty, adUnitEmptyfpd] }, bidRequestSpy); diff --git a/test/spec/modules/kargoBidAdapter_spec.js b/test/spec/modules/kargoBidAdapter_spec.js index c376b444246..8f6dc319c01 100644 --- a/test/spec/modules/kargoBidAdapter_spec.js +++ b/test/spec/modules/kargoBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/kargoBidAdapter.js'; import { config } from 'src/config.js'; import { getStorageManager } from 'src/storageManager.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const utils = require('src/utils'); -const STORAGE = getStorageManager({bidderCode: 'kargo'}); +const STORAGE = getStorageManager({ bidderCode: 'kargo' }); describe('kargo adapter tests', function() { let bid; let outstreamBid; let testBids; let sandbox; let clock; let frozenNow = new Date(); let oldBidderSettings; @@ -53,25 +53,25 @@ describe('kargo adapter tests', function() { userIdAsEids: [ { source: 'adquery.io', - uids: [ { + uids: [{ id: 'adquery-id', atype: 1 - } ] + }] }, { source: 'criteo.com', - uids: [ { + uids: [{ id: 'criteo-id', atype: 1 - } ] + }] }, { source: 'adserver.org', - uids: [ { + uids: [{ id: 'adserver-id', atype: 1, ext: { rtiPartner: 'TDID' } - } ] + }] }, ], floorData: { @@ -82,11 +82,11 @@ describe('kargo adapter tests', function() { config: { ver: '1.0', complete: 1, - nodes: [ { + nodes: [{ asi: 'indirectseller.com', sid: '00001', hp: 1, - } ] + }] } }, }); @@ -96,7 +96,7 @@ describe('kargo adapter tests', function() { placementId: 'foobar' }, mediaTypes: { - banner: { sizes: [ [1, 1] ] } + banner: { sizes: [[1, 1]] } } }); @@ -163,11 +163,11 @@ describe('kargo adapter tests', function() { }, mediaTypes: { banner: { - sizes: [ [970, 250], [1, 1] ] + sizes: [[970, 250], [1, 1]] } }, adUnitCode: 'displayAdunitCode', - sizes: [ [300, 250], [300, 600] ], + sizes: [[300, 250], [300, 600]], bidId: 'randomBidId', bidderRequestId: 'randomBidderRequestId', auctionId: 'randomAuctionId' @@ -183,20 +183,20 @@ describe('kargo adapter tests', function() { video: { context: 'instream', playerSize: [640, 480], - api: [ 1, 2 ], + api: [1, 2], linearity: 1, maxduration: 60, - mimes: [ 'video/mp4', 'video/webm', 'application/javascript' ], + mimes: ['video/mp4', 'video/webm', 'application/javascript'], minduration: 0, placement: 1, - playbackmethod: [ 1, 2, 3 ], + playbackmethod: [1, 2, 3], plcmt: 1, - protocols: [ 2, 3, 5 ], + protocols: [2, 3, 5], skip: 1 } }, adUnitCode: 'instreamAdunitCode', - sizes: [ [300, 250], [300, 600] ], + sizes: [[300, 250], [300, 600]], bidId: 'randomBidId2', bidderRequestId: 'randomBidderRequestId2', auctionId: 'randomAuctionId2' @@ -307,7 +307,7 @@ describe('kargo adapter tests', function() { page: topUrl, reachedTop: true, ref: referer, - stack: [ topUrl ], + stack: [topUrl], topmostLocation: topUrl, }, start: Date.now(), @@ -382,7 +382,7 @@ describe('kargo adapter tests', function() { // Display bid const bidImp = payload.imp[0]; expect(bidImp.id).to.equal('randomBidId'); - expect(bidImp.banner).to.deep.equal({ sizes: [ [970, 250], [1, 1] ] }); + expect(bidImp.banner).to.deep.equal({ sizes: [[970, 250], [1, 1]] }); expect(bidImp.video).to.be.undefined; expect(bidImp.bidRequestCount).to.equal(1); expect(bidImp.bidderRequestCount).to.equal(1); @@ -411,7 +411,7 @@ describe('kargo adapter tests', function() { // General keys expect(payload.aid).to.equal('randomAuctionId'); - expect(payload.device).to.deep.equal({ size: [ window.screen.width, window.screen.height ] }); + expect(payload.device).to.deep.equal({ size: [window.screen.width, window.screen.height] }); expect(payload.ext.ortb2).to.deep.equal(defaultBidParams.ortb2); expect(payload.pbv).to.equal('$prebid.version$'); expect(payload.requestCount).to.equal(spec.buildRequests.callCount - 1); @@ -720,7 +720,7 @@ describe('kargo adapter tests', function() { inventoryCode: 'banner_outstream_test', floor: 1.0, video: { - mimes: [ 'video/mp4' ], + mimes: ['video/mp4'], maxduration: 30, minduration: 6, w: 640, @@ -733,11 +733,11 @@ describe('kargo adapter tests', function() { playerSize: [640, 380] }, banner: { - sizes: [ [970, 250], [1, 1] ] + sizes: [[970, 250], [1, 1]] } }, adUnitCode: 'adunit-code-banner-outstream', - sizes: [ [300, 250], [300, 600], [1, 1, 1], ['flex'] ], + sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], bidId: 'banner-outstream-bid-id', bidderRequestId: 'kargo-request-id', auctionId: 'kargo-auction-id', @@ -749,7 +749,7 @@ describe('kargo adapter tests', function() { inventoryCode: 'banner_outstream_test', floor: 1.0, video: { - mimes: [ 'video/mp4' ], + mimes: ['video/mp4'], maxduration: 30, minduration: 6, w: 640, @@ -758,12 +758,12 @@ describe('kargo adapter tests', function() { }, mediaTypes: { banner: { - sizes: [ [970, 250], [1, 1] ] + sizes: [[970, 250], [1, 1]] }, native: {} }, adUnitCode: 'adunit-code-banner-outstream', - sizes: [ [300, 250], [300, 600], [1, 1, 1], ['flex'] ], + sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], bidId: 'banner-outstream-bid-id', bidderRequestId: 'kargo-request-id', auctionId: 'kargo-auction-id', @@ -775,7 +775,7 @@ describe('kargo adapter tests', function() { inventoryCode: 'banner_outstream_test', floor: 1.0, video: { - mimes: [ 'video/mp4' ], + mimes: ['video/mp4'], maxduration: 30, minduration: 6, w: 640, @@ -790,7 +790,7 @@ describe('kargo adapter tests', function() { native: {}, }, adUnitCode: 'adunit-code-banner-outstream', - sizes: [ [300, 250], [300, 600], [1, 1, 1], ['flex'] ], + sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], bidId: 'banner-outstream-bid-id', bidderRequestId: 'kargo-request-id', auctionId: 'kargo-auction-id', @@ -802,7 +802,7 @@ describe('kargo adapter tests', function() { inventoryCode: 'banner_outstream_test', floor: 1.0, video: { - mimes: [ 'video/mp4' ], + mimes: ['video/mp4'], maxduration: 30, minduration: 6, w: 640, @@ -815,12 +815,12 @@ describe('kargo adapter tests', function() { playerSize: [640, 380] }, banner: { - sizes: [ [970, 250], [1, 1] ] + sizes: [[970, 250], [1, 1]] }, native: {}, }, adUnitCode: 'adunit-code-banner-outstream', - sizes: [ [300, 250], [300, 600], [1, 1, 1], ['flex'] ], + sizes: [[300, 250], [300, 600], [1, 1, 1], ['flex']], bidId: 'banner-outstream-bid-id', bidderRequestId: 'kargo-request-id', auctionId: 'kargo-auction-id', @@ -830,7 +830,7 @@ describe('kargo adapter tests', function() { const payload = getPayloadFromTestBids(testBids); const bannerImp = { - sizes: [ [970, 250], [1, 1] ] + sizes: [[970, 250], [1, 1]] }; const videoImp = { context: 'outstream', @@ -938,7 +938,7 @@ describe('kargo adapter tests', function() { }, ]; - [ 0, null, false, 'foobar' ].forEach(value => testBids.push({ + [0, null, false, 'foobar'].forEach(value => testBids.push({ ...minimumBidParams, bidRequestsCount: value, bidderRequestsCount: value, @@ -1123,14 +1123,14 @@ describe('kargo adapter tests', function() { }); [ - [ 'valid', 'invalidB64', 'cookie' ], - [ 'valid', 'invalidJson', 'cookie' ], - [ 'invalidB64', 'invalidJson', 'none' ], - [ 'invalidB64', 'invalidB64', 'none' ], - [ 'invalidB64', 'valid', 'localStorage' ], - [ 'invalidJson', 'invalidJson', 'none' ], - [ 'invalidJson', 'invalidB64', 'none' ], - [ 'invalidJson', 'valid', 'localStorage' ], + ['valid', 'invalidB64', 'cookie'], + ['valid', 'invalidJson', 'cookie'], + ['invalidB64', 'invalidJson', 'none'], + ['invalidB64', 'invalidB64', 'none'], + ['invalidB64', 'valid', 'localStorage'], + ['invalidJson', 'invalidJson', 'none'], + ['invalidJson', 'invalidB64', 'none'], + ['invalidJson', 'valid', 'localStorage'], ].forEach(config => { it(`uses ${config[2]} if the cookie is ${config[0]} and localStorage is ${config[1]}`, function() { setCrb(config[0], config[1]); @@ -1351,29 +1351,33 @@ describe('kargo adapter tests', function() { ...testBids, { ...minimumBidParams, - ortb2: { device: { sua: { - platform: { - brand: 'macOS', - version: ['12', '6', '0'] - }, - browsers: [ - { - brand: 'Chromium', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Google Chrome', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand', - version: ['99', '0', '0', '0'] + ortb2: { + device: { + sua: { + platform: { + brand: 'macOS', + version: ['12', '6', '0'] + }, + browsers: [ + { + brand: 'Chromium', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Google Chrome', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand', + version: ['99', '0', '0', '0'] + } + ], + mobile: 1, + model: 'model', + source: 1, } - ], - mobile: 1, - model: 'model', - source: 1, - } } } + } + } } ]); expect(payload.device.sua).to.be.undefined; @@ -1383,55 +1387,63 @@ describe('kargo adapter tests', function() { const payload = getPayloadFromTestBids([ { ...minimumBidParams, - ortb2: { device: { sua: { - platform: { - brand: 'macOS', - version: ['12', '6', '0'] - }, - browsers: [ - { - brand: 'Chromium', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Google Chrome', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand', - version: ['99', '0', '0', '0'] + ortb2: { + device: { + sua: { + platform: { + brand: 'macOS', + version: ['12', '6', '0'] + }, + browsers: [ + { + brand: 'Chromium', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Google Chrome', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand', + version: ['99', '0', '0', '0'] + } + ], + mobile: 1, + model: 'model', + source: 1, } - ], - mobile: 1, - model: 'model', - source: 1, - } } } + } + } }, { ...minimumBidParams, - ortb2: { device: { sua: { - platform: { - brand: 'macOS2', - version: ['122', '6', '0'] - }, - browsers: [ - { - brand: 'Chromium2', - version: ['1062', '0', '5249', '119'] - }, - { - brand: 'Google Chrome2', - version: ['102', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand2', - version: ['992', '0', '0', '0'] + ortb2: { + device: { + sua: { + platform: { + brand: 'macOS2', + version: ['122', '6', '0'] + }, + browsers: [ + { + brand: 'Chromium2', + version: ['1062', '0', '5249', '119'] + }, + { + brand: 'Google Chrome2', + version: ['102', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand2', + version: ['992', '0', '0', '0'] + } + ], + mobile: 2, + model: 'model2', + source: 2, } - ], - mobile: 2, - model: 'model2', - source: 2, - } } } + } + } } ]); expect(payload.device.sua).to.deep.equal({ @@ -1460,34 +1472,39 @@ describe('kargo adapter tests', function() { }); it('does not send non-mapped attributes', function() { - const payload = getPayloadFromTestBids([{...minimumBidParams, - ortb2: { device: { sua: { - other: 'value', - objectMissing: { - key: 'value' - }, - platform: { - brand: 'macOS', - version: ['12', '6', '0'] - }, - browsers: [ - { - brand: 'Chromium', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Google Chrome', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand', - version: ['99', '0', '0', '0'] + const payload = getPayloadFromTestBids([{ + ...minimumBidParams, + ortb2: { + device: { + sua: { + other: 'value', + objectMissing: { + key: 'value' + }, + platform: { + brand: 'macOS', + version: ['12', '6', '0'] + }, + browsers: [ + { + brand: 'Chromium', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Google Chrome', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand', + version: ['99', '0', '0', '0'] + } + ], + mobile: 1, + model: 'model', + source: 1, } - ], - mobile: 1, - model: 'model', - source: 1, - } } } + } + } }]); expect(payload.device.sua).to.deep.equal({ platform: { @@ -1523,27 +1540,32 @@ describe('kargo adapter tests', function() { ' ', ' ', ].forEach(value => { - const payload = getPayloadFromTestBids([{...minimumBidParams, - ortb2: { device: { sua: { - platform: value, - browsers: [ - { - brand: 'Chromium', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Google Chrome', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand', - version: ['99', '0', '0', '0'] + const payload = getPayloadFromTestBids([{ + ...minimumBidParams, + ortb2: { + device: { + sua: { + platform: value, + browsers: [ + { + brand: 'Chromium', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Google Chrome', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand', + version: ['99', '0', '0', '0'] + } + ], + mobile: 1, + model: 'model', + source: 1, } - ], - mobile: 1, - model: 'model', - source: 1, - } } } + } + } }]); expect(payload.device.sua, `Value - ${JSON.stringify(value)}`).to.deep.equal({ browsers: [ @@ -1570,29 +1592,33 @@ describe('kargo adapter tests', function() { it('does not send 0 for mobile or source', function() { const payload = getPayloadFromTestBids([{ ...minimumBidParams, - ortb2: { device: { sua: { - platform: { - brand: 'macOS', - version: ['12', '6', '0'] - }, - browsers: [ - { - brand: 'Chromium', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Google Chrome', - version: ['106', '0', '5249', '119'] - }, - { - brand: 'Not;A=Brand', - version: ['99', '0', '0', '0'] + ortb2: { + device: { + sua: { + platform: { + brand: 'macOS', + version: ['12', '6', '0'] + }, + browsers: [ + { + brand: 'Chromium', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Google Chrome', + version: ['106', '0', '5249', '119'] + }, + { + brand: 'Not;A=Brand', + version: ['99', '0', '0', '0'] + } + ], + mobile: 0, + model: 'model', + source: 0, } - ], - mobile: 0, - model: 'model', - source: 0, - } } } + } + } }]); expect(payload.device.sua).to.deep.equal({ platform: { @@ -1666,71 +1692,73 @@ describe('kargo adapter tests', function() { }); describe('interpretResponse', function() { - const response = Object.freeze({ body: { - 1: { - id: 'foo', - cpm: 3, - adm: '
', - width: 320, - height: 50, - metadata: {}, - creativeID: 'bar' - }, - 2: { - id: 'bar', - cpm: 2.5, - adm: '
', - width: 300, - height: 250, - targetingCustom: 'dmpmptest1234', - metadata: { - landingPageDomain: ['https://foobar.com'] + const response = Object.freeze({ + body: { + 1: { + id: 'foo', + cpm: 3, + adm: '
', + width: 320, + height: 50, + metadata: {}, + creativeID: 'bar' }, - creativeID: 'foo' - }, - 3: { - id: 'bar', - cpm: 2.5, - adm: '
', - width: 300, - height: 250, - creativeID: 'foo' - }, - 4: { - id: 'bar', - cpm: 2.5, - adm: '
', - width: 300, - height: 250, - mediaType: 'banner', - metadata: {}, - creativeID: 'foo', - currency: 'EUR' - }, - 5: { - id: 'bar', - cpm: 2.5, - adm: '', - width: 300, - height: 250, - mediaType: 'video', - metadata: {}, - creativeID: 'foo', - currency: 'EUR' - }, - 6: { - id: 'bar', - cpm: 2.5, - adm: '', - admUrl: 'https://foobar.com/vast_adm', - width: 300, - height: 250, - mediaType: 'video', - metadata: {}, - creativeID: 'foo', - currency: 'EUR' + 2: { + id: 'bar', + cpm: 2.5, + adm: '
', + width: 300, + height: 250, + targetingCustom: 'dmpmptest1234', + metadata: { + landingPageDomain: ['https://foobar.com'] + }, + creativeID: 'foo' + }, + 3: { + id: 'bar', + cpm: 2.5, + adm: '
', + width: 300, + height: 250, + creativeID: 'foo' + }, + 4: { + id: 'bar', + cpm: 2.5, + adm: '
', + width: 300, + height: 250, + mediaType: 'banner', + metadata: {}, + creativeID: 'foo', + currency: 'EUR' + }, + 5: { + id: 'bar', + cpm: 2.5, + adm: '', + width: 300, + height: 250, + mediaType: 'video', + metadata: {}, + creativeID: 'foo', + currency: 'EUR' + }, + 6: { + id: 'bar', + cpm: 2.5, + adm: '', + admUrl: 'https://foobar.com/vast_adm', + width: 300, + height: 250, + mediaType: 'video', + metadata: {}, + creativeID: 'foo', + currency: 'EUR' + } } - }}); + }); const bidderRequest = Object.freeze({ currency: 'USD', bids: [{ @@ -1886,18 +1914,22 @@ describe('kargo adapter tests', function() { }); it('adds landingPageDomain data', function() { - const response = spec.interpretResponse({ body: { 0: { - metadata: { - landingPageDomain: [ - 'https://foo.com', - 'https://bar.com' - ] + const response = spec.interpretResponse({ + body: { + 0: { + metadata: { + landingPageDomain: [ + 'https://foo.com', + 'https://bar.com' + ] + } + } } - } } }, {}); + }, {}); expect(response[0].meta).to.deep.equal({ mediaType: 'banner', clickUrl: 'https://foo.com', - advertiserDomains: [ 'https://foo.com', 'https://bar.com' ] + advertiserDomains: ['https://foo.com', 'https://bar.com'] }); }); @@ -2089,7 +2121,7 @@ describe('kargo adapter tests', function() { describe('supportedMediaTypes', function() { it('exposes video and banner', function() { - expect(spec.supportedMediaTypes).to.deep.equal([ 'banner', 'video' ]); + expect(spec.supportedMediaTypes).to.deep.equal(['banner', 'video']); }); }); diff --git a/test/spec/modules/kimberliteBidAdapter_spec.js b/test/spec/modules/kimberliteBidAdapter_spec.js index af1e027ca4c..19942879154 100644 --- a/test/spec/modules/kimberliteBidAdapter_spec.js +++ b/test/spec/modules/kimberliteBidAdapter_spec.js @@ -75,7 +75,7 @@ describe('kimberliteBidAdapter', function () { bidRequests = [ { mediaTypes: { - [BANNER]: {sizes: sizes} + [BANNER]: { sizes: sizes } }, params: { placementId: 'test-placement' @@ -188,7 +188,7 @@ describe('kimberliteBidAdapter', function () { { bidId: 1, mediaTypes: { - banner: {sizes: sizes} + banner: { sizes: sizes } }, params: { placementId: 'test-placement' @@ -252,7 +252,7 @@ describe('kimberliteBidAdapter', function () { }); it('fails on empty response', function () { - const bids = spec.interpretResponse({body: ''}, bidRequest); + const bids = spec.interpretResponse({ body: '' }, bidRequest); assert.empty(bids); }); }); diff --git a/test/spec/modules/kinessoIdSystem_spec.js b/test/spec/modules/kinessoIdSystem_spec.js index c2c0b24aeb5..fab5ec781a6 100644 --- a/test/spec/modules/kinessoIdSystem_spec.js +++ b/test/spec/modules/kinessoIdSystem_spec.js @@ -1,10 +1,10 @@ import sinon from 'sinon'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {kinessoIdSubmodule} from '../../../modules/kinessoIdSystem.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { kinessoIdSubmodule } from '../../../modules/kinessoIdSystem.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; import * as utils from '../../../src/utils.js'; import * as ajaxLib from '../../../src/ajax.js'; -import {expect} from 'chai/index.mjs'; +import { expect } from 'chai/index.mjs'; describe('kinesso ID', () => { describe('eid', () => { @@ -51,7 +51,7 @@ describe('kinesso ID', () => { it('decodes a string id', function() { const val = 'abc'; const result = kinessoIdSubmodule.decode(val); - expect(result).to.deep.equal({kpuid: val}); + expect(result).to.deep.equal({ kpuid: val }); expect(utils.logInfo.calledOnce).to.be.true; }); }); @@ -72,28 +72,28 @@ describe('kinesso ID', () => { }); it('requires numeric accountid', function() { - const res = kinessoIdSubmodule.getId({params: {accountid: 'bad'}}); + const res = kinessoIdSubmodule.getId({ params: { accountid: 'bad' } }); expect(res).to.be.undefined; expect(utils.logError.calledOnce).to.be.true; expect(ajaxStub.called).to.be.false; }); it('skips on coppa requests', function() { - const res = kinessoIdSubmodule.getId({params: {accountid: 7}}, {coppa: true}); + const res = kinessoIdSubmodule.getId({ params: { accountid: 7 } }, { coppa: true }); expect(res).to.be.undefined; expect(utils.logInfo.calledOnce).to.be.true; expect(ajaxStub.called).to.be.false; }); it('generates an id and posts to the endpoint', function() { - const consent = {gdpr: {gdprApplies: true, consentString: 'CONSENT'}, usp: '1NNN'}; - const result = kinessoIdSubmodule.getId({params: {accountid: 10}}, consent); + const consent = { gdpr: { gdprApplies: true, consentString: 'CONSENT' }, usp: '1NNN' }; + const result = kinessoIdSubmodule.getId({ params: { accountid: 10 } }, consent); expect(result).to.have.property('id').that.is.a('string').with.length(26); expect(ajaxStub.calledOnce).to.be.true; const [url,, payload, options] = ajaxStub.firstCall.args; expect(url).to.equal('https://id.knsso.com/id?accountid=10&us_privacy=1NNN&gdpr=1&gdpr_consent=CONSENT'); - expect(options).to.deep.equal({method: 'POST', withCredentials: true}); + expect(options).to.deep.equal({ method: 'POST', withCredentials: true }); expect(JSON.parse(payload)).to.have.property('id', result.id); }); }); diff --git a/test/spec/modules/kiviadsBidAdapter_spec.js b/test/spec/modules/kiviadsBidAdapter_spec.js index d7f9a233c9d..d7cbd189782 100644 --- a/test/spec/modules/kiviadsBidAdapter_spec.js +++ b/test/spec/modules/kiviadsBidAdapter_spec.js @@ -483,7 +483,7 @@ describe('KiviAdsBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -492,9 +492,7 @@ describe('KiviAdsBidAdapter', function () { expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0`) }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -503,7 +501,7 @@ describe('KiviAdsBidAdapter', function () { expect(syncData[0].url).to.equal(`${syncUrl}/image?pbjs=1&ccpa_consent=1---&coppa=0`) }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/koblerBidAdapter_spec.js b/test/spec/modules/koblerBidAdapter_spec.js index 4e70ac6f9f3..78dd23a60a8 100644 --- a/test/spec/modules/koblerBidAdapter_spec.js +++ b/test/spec/modules/koblerBidAdapter_spec.js @@ -1,9 +1,9 @@ -import {expect} from 'chai'; -import {spec} from 'modules/koblerBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/koblerBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; -import {getRefererInfo} from 'src/refererDetection.js'; +import { getRefererInfo } from 'src/refererDetection.js'; import { setConfig as setCurrencyConfig } from '../../../modules/currency.js'; import { addFPDToBidderRequest } from '../../helpers/fpd.js'; @@ -26,9 +26,9 @@ function createBidderRequest(auctionId, timeout, pageUrl, gdprVendorData = {}, p }; } -function createValidBidRequest(params, bidId, sizes) { +function createValidBidRequest(params, bidId, sizes, adUnitCode) { const validBidRequest = { - adUnitCode: 'adunit-code', + adUnitCode: adUnitCode || 'adunit-code', bidId: bidId || '22c4871113f461', bidder: 'kobler', bidderRequestId: '15246a574e859f', @@ -451,7 +451,8 @@ describe('KoblerAdapter', function () { dealIds: ['623472534328234'] }, '953ee65d-d18a-484f-a840-d3056185a060', - [[400, 600]] + [[400, 600]], + 'ad-unit-1' ), createValidBidRequest( { @@ -459,12 +460,14 @@ describe('KoblerAdapter', function () { dealIds: ['92368234753283', '263845832942'] }, '8320bf79-9d90-4a17-87c6-5d505706a921', - [[400, 500], [200, 250], [300, 350]] + [[400, 500], [200, 250], [300, 350]], + 'ad-unit-2' ), createValidBidRequest( undefined, 'd0de713b-32e3-4191-a2df-a007f08ffe72', - [[800, 900]] + [[800, 900]], + 'ad-unit-3' ) ]; const bidderRequest = createBidderRequest( @@ -520,6 +523,11 @@ describe('KoblerAdapter', function () { id: '623472534328234' } ] + }, + ext: { + prebid: { + adunitcode: 'ad-unit-1' + } } }, { @@ -553,6 +561,11 @@ describe('KoblerAdapter', function () { id: '263845832942' } ] + }, + ext: { + prebid: { + adunitcode: 'ad-unit-2' + } } }, { @@ -569,7 +582,12 @@ describe('KoblerAdapter', function () { }, bidfloor: 0, bidfloorcur: 'USD', - pmp: {} + pmp: {}, + ext: { + prebid: { + adunitcode: 'ad-unit-3' + } + } } ], device: { @@ -723,12 +741,18 @@ describe('KoblerAdapter', function () { const bidderRequest = { refererInfo }; return addFPDToBidderRequest(bidderRequest).then(res => { JSON.parse(spec.buildRequests(validBidRequests, res).data); - const bids = spec.interpretResponse({ body: { seatbid: [{ bid: [{ - originalCpm: 1.532, - price: 8.341, - currency: 'NOK', - nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=${AUCTION_PRICE}&sp_cur=${AUCTION_PRICE_CURRENCY}&asp=${AD_SERVER_PRICE}&asp_cur=${AD_SERVER_PRICE_CURRENCY}', - }]}]}}, { bidderRequest: res }); + const bids = spec.interpretResponse({ + body: { + seatbid: [{ + bid: [{ + originalCpm: 1.532, + price: 8.341, + currency: 'NOK', + nurl: 'https://atag.essrtb.com/serve/prebid_win_notification?payload=sdhfusdaobfadslf234324&sp=${AUCTION_PRICE}&sp_cur=${AUCTION_PRICE_CURRENCY}&asp=${AD_SERVER_PRICE}&asp_cur=${AD_SERVER_PRICE_CURRENCY}', + }] + }] + } + }, { bidderRequest: res }); const bidToWon = bids[0]; bidToWon.adserverTargeting = { hb_pb: 8 diff --git a/test/spec/modules/krushmediaBidAdapter_spec.js b/test/spec/modules/krushmediaBidAdapter_spec.js index 98bdbcbb855..044d9d4f26b 100644 --- a/test/spec/modules/krushmediaBidAdapter_spec.js +++ b/test/spec/modules/krushmediaBidAdapter_spec.js @@ -483,7 +483,7 @@ describe('KrushmediabBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -492,9 +492,7 @@ describe('KrushmediabBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.krushmedia.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -503,7 +501,7 @@ describe('KrushmediabBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.krushmedia.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/kubientBidAdapter_spec.js b/test/spec/modules/kubientBidAdapter_spec.js index 4a162e8575e..074aef4d3ae 100644 --- a/test/spec/modules/kubientBidAdapter_spec.js +++ b/test/spec/modules/kubientBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect, assert } from 'chai'; import { spec } from 'modules/kubientBidAdapter.js'; import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; +import { config } from '../../../src/config.js'; function encodeQueryData(data) { return Object.keys(data).map(function(key) { @@ -117,8 +117,8 @@ describe('KubientAdapter', function () { config.resetConfig(); }); it('Creates Banner 1 ServerRequest object with method, URL and data', function () { - config.setConfig({'coppa': false}); - const serverRequests = spec.buildRequests([bidBanner], Object.assign({}, bidderRequest, {bids: [bidBanner]})); + config.setConfig({ 'coppa': false }); + const serverRequests = spec.buildRequests([bidBanner], Object.assign({}, bidderRequest, { bids: [bidBanner] })); expect(serverRequests).to.be.an('array'); for (let i = 0; i < serverRequests.length; i++) { const serverRequest = serverRequests[i]; @@ -153,8 +153,8 @@ describe('KubientAdapter', function () { config.resetConfig(); }); it('Creates Video 1 ServerRequest object with method, URL and data', function () { - config.setConfig({'coppa': false}); - const serverRequests = spec.buildRequests([bidVideo], Object.assign({}, bidderRequest, {bids: [bidVideo]})); + config.setConfig({ 'coppa': false }); + const serverRequests = spec.buildRequests([bidVideo], Object.assign({}, bidderRequest, { bids: [bidVideo] })); expect(serverRequests).to.be.an('array'); for (let i = 0; i < serverRequests.length; i++) { const serverRequest = serverRequests[i]; @@ -190,8 +190,8 @@ describe('KubientAdapter', function () { config.resetConfig(); }); it('Creates Banner 2 ServerRequest object with method, URL and data with bidBanner', function () { - config.setConfig({'coppa': true}); - const serverRequests = spec.buildRequests([bidBanner], Object.assign({}, bidderRequest, {bids: [bidBanner]})); + config.setConfig({ 'coppa': true }); + const serverRequests = spec.buildRequests([bidBanner], Object.assign({}, bidderRequest, { bids: [bidBanner] })); expect(serverRequests).to.be.an('array'); for (let i = 0; i < serverRequests.length; i++) { const serverRequest = serverRequests[i]; @@ -227,8 +227,8 @@ describe('KubientAdapter', function () { config.resetConfig(); }); it('Creates Video 2 ServerRequest object with method, URL and data', function () { - config.setConfig({'coppa': true}); - const serverRequests = spec.buildRequests([bidVideo], Object.assign({}, bidderRequest, {bids: [bidVideo]})); + config.setConfig({ 'coppa': true }); + const serverRequests = spec.buildRequests([bidVideo], Object.assign({}, bidderRequest, { bids: [bidVideo] })); expect(serverRequests).to.be.an('array'); for (let i = 0; i < serverRequests.length; i++) { const serverRequest = serverRequests[i]; @@ -300,7 +300,7 @@ describe('KubientAdapter', function () { cur: 'USD', netRevenue: false, ttl: 360, - meta: {adomain: ['google.com', 'yahoo.com']} + meta: { adomain: ['google.com', 'yahoo.com'] } } ] } @@ -351,7 +351,7 @@ describe('KubientAdapter', function () { cur: 'USD', netRevenue: false, ttl: 360, - meta: {adomain: ['google.com', 'yahoo.com']} + meta: { adomain: ['google.com', 'yahoo.com'] } } ] } diff --git a/test/spec/modules/kueezRtbBidAdapter_spec.js b/test/spec/modules/kueezRtbBidAdapter_spec.js index 08e4fefdaf8..67ea5b7363c 100644 --- a/test/spec/modules/kueezRtbBidAdapter_spec.js +++ b/test/spec/modules/kueezRtbBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, @@ -7,10 +7,10 @@ import { createFirstPartyData, } from 'modules/kueezRtbBidAdapter.js'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; import { hashCode, extractPID, @@ -21,7 +21,7 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -102,9 +102,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -121,7 +121,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -192,9 +192,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -207,7 +206,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -333,9 +332,9 @@ describe('KueezRtbBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -408,9 +407,9 @@ describe('KueezRtbBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -455,7 +454,7 @@ describe('KueezRtbBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -464,7 +463,7 @@ describe('KueezRtbBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.kueezrtb.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -472,7 +471,7 @@ describe('KueezRtbBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.kueezrtb.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -484,7 +483,7 @@ describe('KueezRtbBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.kueezrtb.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -502,7 +501,7 @@ describe('KueezRtbBidAdapter', function () { applicableSections: [7] } - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); expect(result).to.deep.equal([{ 'url': 'https://sync.kueezrtb.com/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', @@ -518,12 +517,12 @@ describe('KueezRtbBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -596,9 +595,9 @@ describe('KueezRtbBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -619,7 +618,7 @@ describe('KueezRtbBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -630,11 +629,11 @@ describe('KueezRtbBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -649,7 +648,7 @@ describe('KueezRtbBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -664,11 +663,11 @@ describe('KueezRtbBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -681,18 +680,18 @@ describe('KueezRtbBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -752,7 +751,7 @@ describe('KueezRtbBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -768,8 +767,8 @@ describe('KueezRtbBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/leagueMBidAdapter_spec.js b/test/spec/modules/leagueMBidAdapter_spec.js new file mode 100644 index 00000000000..a85b7d65746 --- /dev/null +++ b/test/spec/modules/leagueMBidAdapter_spec.js @@ -0,0 +1,441 @@ +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/leagueMBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; + +const ENDPOINT = 'https://pbjs.league-m.media'; + +const defaultRequest = { + tmax: 0, + adUnitCode: 'test', + bidId: '1', + requestId: 'qwerty', + ortb2: { + source: { + tid: 'auctionId' + } + }, + ortb2Imp: { + ext: { + tid: 'tr1', + } + }, + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [300, 200] + ] + } + }, + bidder: 'leagueM', + params: { + pid: 'aa8217e20131c095fe9dba67981040b0', + ext: {} + }, + bidRequestsCount: 1 +}; + +const defaultRequestVideo = deepClone(defaultRequest); +defaultRequestVideo.mediaTypes = { + video: { + playerSize: [640, 480], + context: 'instream', + skippable: true + } +}; + +const videoBidderRequest = { + bidderCode: 'leagueM', + bids: [{ mediaTypes: { video: {} }, bidId: 'qwerty' }] +}; + +const displayBidderRequest = { + bidderCode: 'leagueM', + bids: [{ bidId: 'qwerty' }] +}; + +describe('leagueMBidAdapter', () => { + describe('isBidRequestValid', function () { + it('should return false when request params is missing', function () { + const invalidRequest = deepClone(defaultRequest); + delete invalidRequest.params; + expect(spec.isBidRequestValid(invalidRequest)).to.equal(false); + }); + + it('should return false when required pid param is missing', function () { + const invalidRequest = deepClone(defaultRequest); + delete invalidRequest.params.pid; + expect(spec.isBidRequestValid(invalidRequest)).to.equal(false); + }); + + it('should return false when video.playerSize is missing', function () { + const invalidRequest = deepClone(defaultRequestVideo); + delete invalidRequest.mediaTypes.video.playerSize; + expect(spec.isBidRequestValid(invalidRequest)).to.equal(false); + }); + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(defaultRequest)).to.equal(true); + }); + }); + + describe('buildRequests', function () { + beforeEach(function () { + config.resetConfig(); + }); + + it('should send request with correct structure', function () { + const request = spec.buildRequests([defaultRequest], {}); + expect(request.method).to.equal('POST'); + expect(request.url).to.equal(ENDPOINT + '/bid'); + expect(request.options).to.have.property('contentType').and.to.equal('application/json'); + expect(request).to.have.property('data'); + }); + + it('should build basic request structure', function () { + const request = JSON.parse(spec.buildRequests([defaultRequest], {}).data)[0]; + expect(request).to.have.property('tmax').and.to.equal(defaultRequest.tmax); + expect(request).to.have.property('bidId').and.to.equal(defaultRequest.bidId); + expect(request).to.have.property('auctionId').and.to.equal(defaultRequest.ortb2.source.tid); + expect(request).to.have.property('transactionId').and.to.equal(defaultRequest.ortb2Imp.ext.tid); + expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); + expect(request).to.have.property('bc').and.to.equal(1); + expect(request).to.have.property('floor').and.to.equal(null); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); + expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); + expect(request).to.have.property('userEids').and.to.deep.equal([]); + expect(request).to.have.property('usPrivacy').and.to.equal(''); + expect(request).to.have.property('sizes').and.to.deep.equal(['300x250', '300x200']); + expect(request).to.have.property('ext').and.to.deep.equal({}); + expect(request).to.have.property('env').and.to.deep.equal({ + pid: 'aa8217e20131c095fe9dba67981040b0' + }); + expect(request).to.have.property('device').and.to.deep.equal({ + ua: navigator.userAgent, + lang: navigator.language + }); + }); + + it('should build request with schain', function () { + const schainRequest = deepClone(defaultRequest); + const bidderRequest = { + ortb2: { + source: { + ext: { + schain: { + ver: '1.0' + } + } + } + } + }; + const request = JSON.parse(spec.buildRequests([schainRequest], bidderRequest).data)[0]; + expect(request).to.have.property('schain').and.to.deep.equal({ + ver: '1.0' + }); + }); + + it('should build request with location', function () { + const bidderRequest = { + refererInfo: { + page: 'page', + location: 'location', + domain: 'domain', + ref: 'ref', + isAmp: false + } + }; + const request = JSON.parse(spec.buildRequests([defaultRequest], bidderRequest).data)[0]; + expect(request).to.have.property('location'); + const location = request.location; + expect(location).to.have.property('page').and.to.equal('page'); + expect(location).to.have.property('location').and.to.equal('location'); + expect(location).to.have.property('domain').and.to.equal('domain'); + expect(location).to.have.property('ref').and.to.equal('ref'); + expect(location).to.have.property('isAmp').and.to.equal(false); + }); + + it('should build request with ortb2 info', function () { + const ortb2Request = deepClone(defaultRequest); + ortb2Request.ortb2 = { + site: { + name: 'name' + } + }; + const request = JSON.parse(spec.buildRequests([ortb2Request], {}).data)[0]; + expect(request).to.have.property('ortb2').and.to.deep.equal({ + site: { + name: 'name' + } + }); + }); + + it('should build request with ortb2Imp info', function () { + const ortb2ImpRequest = deepClone(defaultRequest); + ortb2ImpRequest.ortb2Imp = { + ext: { + data: { + pbadslot: 'home1', + adUnitSpecificAttribute: '1' + } + } + }; + const request = JSON.parse(spec.buildRequests([ortb2ImpRequest], {}).data)[0]; + expect(request).to.have.property('ortb2Imp').and.to.deep.equal({ + ext: { + data: { + pbadslot: 'home1', + adUnitSpecificAttribute: '1' + } + } + }); + }); + + it('should build request with valid bidfloor', function () { + const bfRequest = deepClone(defaultRequest); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); + const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; + expect(request).to.have.property('floor').and.to.equal(5); + }); + + it('should build request with usp consent data if applies', function () { + const bidderRequest = { + uspConsent: '1YA-' + }; + const request = JSON.parse(spec.buildRequests([defaultRequest], bidderRequest).data)[0]; + expect(request).to.have.property('usPrivacy').and.equals('1YA-'); + }); + + it('should build request with extended ids', function () { + const idRequest = deepClone(defaultRequest); + idRequest.userIdAsEids = [ + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } + ]; + const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; + expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); + }); + + it('should build request with video', function () { + const request = JSON.parse(spec.buildRequests([defaultRequestVideo], {}).data)[0]; + expect(request).to.have.property('video').and.to.deep.equal({ + playerSize: [640, 480], + context: 'instream', + skippable: true + }); + expect(request).to.have.property('sizes').and.to.deep.equal(['640x480']); + }); + }); + + describe('interpretResponse', function () { + it('should return empty bids', function () { + const serverResponse = { + body: { + data: null + } + }; + + const invalidResponse = spec.interpretResponse(serverResponse, {}); + expect(invalidResponse).to.be.an('array').that.is.empty; + }); + + it('should interpret valid response', function () { + const serverResponse = { + body: { + data: [{ + requestId: 'qwerty', + cpm: 1, + currency: 'USD', + width: 300, + height: 250, + ttl: 600, + meta: { + advertiserDomains: ['leagueM'] + }, + ext: { + pixels: [ + ['iframe', 'surl1'], + ['image', 'surl2'], + ] + } + }] + } + }; + + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); + const bid = validResponse[0]; + expect(validResponse).to.be.an('array').that.is.not.empty; + expect(bid.requestId).to.equal('qwerty'); + expect(bid.cpm).to.equal(1); + expect(bid.currency).to.equal('USD'); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.ttl).to.equal(600); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['leagueM'] }); + }); + + it('should interpret valid banner response', function () { + const serverResponse = { + body: { + data: [{ + requestId: 'qwerty', + cpm: 1, + currency: 'USD', + width: 300, + height: 250, + ttl: 600, + mediaType: 'banner', + creativeId: 'demo-banner', + ad: 'ad', + meta: {} + }] + } + }; + + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); + const bid = validResponseBanner[0]; + expect(validResponseBanner).to.be.an('array').that.is.not.empty; + expect(bid.mediaType).to.equal('banner'); + expect(bid.creativeId).to.equal('demo-banner'); + expect(bid.ad).to.equal('ad'); + }); + + it('should interpret valid video response', function () { + const serverResponse = { + body: { + data: [{ + requestId: 'qwerty', + cpm: 1, + currency: 'USD', + width: 600, + height: 480, + ttl: 600, + mediaType: 'video', + creativeId: 'demo-video', + ad: 'vast-xml', + meta: {} + }] + } + }; + + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: videoBidderRequest }); + const bid = validResponseBanner[0]; + expect(validResponseBanner).to.be.an('array').that.is.not.empty; + expect(bid.mediaType).to.equal('video'); + expect(bid.creativeId).to.equal('demo-video'); + expect(bid.ad).to.equal('vast-xml'); + }); + }); + + describe('getUserSyncs', function () { + it('should handle no params', function () { + const opts = spec.getUserSyncs({}, []); + expect(opts).to.be.an('array').that.is.empty; + }); + + it('should return empty if sync is not allowed', function () { + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); + expect(opts).to.be.an('array').that.is.empty; + }); + + it('should allow iframe sync', function () { + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ + body: { + data: [{ + requestId: 'qwerty', + ext: { + pixels: [ + ['iframe', 'surl1?a=b'], + ['image', 'surl2?a=b'], + ] + } + }] + } + }]); + expect(opts.length).to.equal(1); + expect(opts[0].type).to.equal('iframe'); + expect(opts[0].url).to.equal('surl1?a=b&us_privacy=&gdpr=0&gdpr_consent='); + }); + + it('should allow pixel sync', function () { + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ + body: { + data: [{ + requestId: 'qwerty', + ext: { + pixels: [ + ['iframe', 'surl1?a=b'], + ['image', 'surl2?a=b'], + ] + } + }] + } + }]); + expect(opts.length).to.equal(1); + expect(opts[0].type).to.equal('image'); + expect(opts[0].url).to.equal('surl2?a=b&us_privacy=&gdpr=0&gdpr_consent='); + }); + + it('should allow pixel sync and parse consent params', function () { + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ + body: { + data: [{ + requestId: 'qwerty', + ext: { + pixels: [ + ['iframe', 'surl1?a=b'], + ['image', 'surl2?a=b'], + ] + } + }] + } + }], { + gdprApplies: 1, + consentString: '1YA-' + }); + expect(opts.length).to.equal(1); + expect(opts[0].type).to.equal('image'); + expect(opts[0].url).to.equal('surl2?a=b&us_privacy=&gdpr=1&gdpr_consent=1YA-'); + }); + }); + + describe('getBidFloor', function () { + it('should return null when getFloor is not a function', () => { + const bid = { getFloor: 2 }; + const result = getBidFloor(bid); + expect(result).to.be.null; + }); + + it('should return null when getFloor doesnt return an object', () => { + const bid = { getFloor: () => 2 }; + const result = getBidFloor(bid); + expect(result).to.be.null; + }); + + it('should return null when floor is not a number', () => { + const bid = { + getFloor: () => ({ floor: 'string', currency: 'USD' }) + }; + const result = getBidFloor(bid); + expect(result).to.be.null; + }); + + it('should return null when currency is not USD', () => { + const bid = { + getFloor: () => ({ floor: 5, currency: 'EUR' }) + }; + const result = getBidFloor(bid); + expect(result).to.be.null; + }); + + it('should return floor value when everything is correct', () => { + const bid = { + getFloor: () => ({ floor: 5, currency: 'USD' }) + }; + const result = getBidFloor(bid); + expect(result).to.equal(5); + }); + }); +}); diff --git a/test/spec/modules/limelightDigitalBidAdapter_spec.js b/test/spec/modules/limelightDigitalBidAdapter_spec.js index 31b8530c7eb..a4cff04599b 100644 --- a/test/spec/modules/limelightDigitalBidAdapter_spec.js +++ b/test/spec/modules/limelightDigitalBidAdapter_spec.js @@ -1,5 +1,6 @@ import { expect } from 'chai'; import { spec } from '../../../modules/limelightDigitalBidAdapter.js'; +import { deepAccess } from '../../../src/utils.js'; describe('limelightDigitalAdapter', function () { const bid1 = { @@ -42,25 +43,9 @@ describe('limelightDigitalAdapter', function () { } ] } - ], - ortb2: { - source: { - ext: { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - } - ] - } - } - } - } - } + ] + }; + const bid2 = { bidId: '58ee9870c3164a', bidder: 'limelightDigital', @@ -77,13 +62,17 @@ describe('limelightDigitalAdapter', function () { }, placementCode: 'placement_1', auctionId: '482f88de-29ab-45c8-981a-d25e39454a34', - sizes: [[350, 200]], + mediaTypes: { + banner: { + sizes: [[350, 200]] + } + }, ortb2Imp: { ext: { - gpid: '/1111/homepage#300x250', + gpid: '/1111/homepage#350x200', tid: '738d5915-6651-43b9-9b6b-d50517350917', data: { - 'pbadslot': '/1111/homepage#300x250' + 'pbadslot': '/1111/homepage#350x200' } } }, @@ -96,30 +85,9 @@ describe('limelightDigitalAdapter', function () { } ] } - ], - ortb2: { - source: { - ext: { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - }, - { - asi: 'example1.com', - sid: '2', - hp: 1 - } - ] - } - } - } - } - } + ] + }; + const bid3 = { bidId: '019645c7d69460', bidder: 'limelightDigital', @@ -137,103 +105,77 @@ describe('limelightDigitalAdapter', function () { }, placementCode: 'placement_2', auctionId: 'e4771143-6aa7-41ec-8824-ced4342c96c8', - sizes: [[800, 600]], - ortb2Imp: { - ext: { - gpid: '/1111/homepage#300x250', - tid: '738d5915-6651-43b9-9b6b-d50517350917', - data: { - 'pbadslot': '/1111/homepage#300x250' - } - } - }, - userIdAsEids: [ - { - source: 'test3.org', - uids: [ - { - id: '345', - }, - { - id: '456', - } - ] - } - ], - ortb2: { - source: { - ext: { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - } - ] - } - } + mediaTypes: { + video: { + context: 'instream', + playerSize: [[800, 600]], + mimes: ['video/mp4', 'application/javascript'], + protocols: [2, 3, 5, 6], + maxduration: 60, + minduration: 3, + api: [2], + playbackmethod: [1] } - } - } - const bid4 = { - bidId: '019645c7d69460', - bidder: 'limelightDigital', - bidderRequestId: 'f2b15f89e77ba6', - params: { - host: 'exchange.ortb.net', - adUnitId: 789, - adUnitType: 'video', - custom1: 'custom1', - custom2: 'custom2', - custom3: 'custom3', - custom4: 'custom4', - custom5: 'custom5' - }, - placementCode: 'placement_2', - auctionId: 'e4771143-6aa7-41ec-8824-ced4342c96c8', - video: { - playerSize: [800, 600] }, ortb2Imp: { ext: { - gpid: '/1111/homepage#300x250', + gpid: '/1111/homepage#800x600', tid: '738d5915-6651-43b9-9b6b-d50517350917', data: { - 'pbadslot': '/1111/homepage#300x250' + 'pbadslot': '/1111/homepage#800x600' } } }, userIdAsEids: [ { - source: 'test.org', + source: 'test3.org', uids: [ { - id: '111', + id: '345', } ] } - ], - ortb2: { - source: { - ext: { - schain: { - ver: '1.0', - complete: 1, - nodes: [ - { - asi: 'example.com', - sid: '1', - hp: 1 - } - ] - } - } - } - } - } + ] + }; + + describe('isBidRequestValid', function() { + it('should return true when required params found', function() { + expect(spec.isBidRequestValid(bid1)).to.equal(true); + expect(spec.isBidRequestValid(bid2)).to.equal(true); + expect(spec.isBidRequestValid(bid3)).to.equal(true); + }); + + it('should return true when adUnitId is zero', function() { + const bidWithZeroId = { ...bid1, params: { ...bid1.params, adUnitId: 0 } }; + expect(spec.isBidRequestValid(bidWithZeroId)).to.equal(true); + }); + + it('should return false when required params are not passed', function() { + const bidFailed = { + bidder: 'limelightDigital', + bidderRequestId: '145e1d6a7837c9', + params: { + adUnitId: 123, + adUnitType: 'banner' + }, + placementCode: 'placement_0', + auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2' + }; + expect(spec.isBidRequestValid(bidFailed)).to.equal(false); + }); + + it('should return false when host is missing', function() { + const bidWithoutHost = { ...bid1, params: { ...bid1.params } }; + delete bidWithoutHost.params.host; + expect(spec.isBidRequestValid(bidWithoutHost)).to.equal(false); + }); + + it('should return false when adUnitType is missing', function() { + const bidWithoutType = { ...bid1, params: { ...bid1.params } }; + delete bidWithoutType.params.adUnitType; + expect(spec.isBidRequestValid(bidWithoutType)).to.equal(false); + }); + }); describe('buildRequests', function () { const bidderRequest = { @@ -245,620 +187,636 @@ describe('limelightDigitalAdapter', function () { mobile: 1, architecture: 'arm' } + }, + site: { + page: 'https://example.com/page' } }, refererInfo: { - page: 'testPage' - } - } - const serverRequests = spec.buildRequests([bid1, bid2, bid3, bid4], bidderRequest) - it('Creates two ServerRequests', function() { - expect(serverRequests).to.exist - expect(serverRequests).to.have.lengthOf(2) - }) - serverRequests.forEach(serverRequest => { - it('Creates a ServerRequest object with method, URL and data', function () { - expect(serverRequest).to.exist - expect(serverRequest.method).to.exist - expect(serverRequest.url).to.exist - expect(serverRequest.data).to.exist - }) - it('Returns POST method', function () { - expect(serverRequest.method).to.equal('POST') - }) - it('Returns valid data if array of bids is valid', function () { - const data = serverRequest.data; - expect(data).to.be.an('object'); - expect(data).to.have.all.keys( - 'deviceWidth', - 'deviceHeight', - 'secure', - 'adUnits', - 'sua', - 'page', - 'ortb2', - 'refererInfo' - ); - expect(data.deviceWidth).to.be.a('number'); - expect(data.deviceHeight).to.be.a('number'); - expect(data.secure).to.be.a('boolean'); - data.adUnits.forEach(adUnit => { - expect(adUnit).to.have.all.keys( - 'id', - 'bidId', - 'type', - 'sizes', - 'transactionId', - 'publisherId', - 'userIdAsEids', - 'supplyChain', - 'custom1', - 'custom2', - 'custom3', - 'custom4', - 'custom5', - 'ortb2Imp' - ); - expect(adUnit.id).to.be.a('number'); - expect(adUnit.bidId).to.be.a('string'); - expect(adUnit.type).to.be.a('string'); - expect(adUnit.transactionId).to.be.a('string'); - expect(adUnit.sizes).to.be.an('array'); - expect(adUnit.userIdAsEids).to.be.an('array'); - expect(adUnit.supplyChain).to.be.an('object'); - expect(adUnit.custom1).to.be.a('string'); - expect(adUnit.custom2).to.be.a('string'); - expect(adUnit.custom3).to.be.a('string'); - expect(adUnit.custom4).to.be.a('string'); - expect(adUnit.custom5).to.be.a('string'); - expect(adUnit.ortb2Imp).to.be.an('object'); - }) - expect(data.sua.browsers).to.be.a('array'); - expect(data.sua.platform).to.be.a('array'); - expect(data.sua.mobile).to.be.a('number'); - expect(data.sua.architecture).to.be.a('string'); - expect(data.page).to.be.a('string'); - expect(data.page).to.be.equal('testPage'); - expect(data.ortb2).to.be.an('object'); - }) - }) - it('Returns valid URL', function () { - expect(serverRequests[0].url).to.equal('https://exchange.ortb.net/hb') - expect(serverRequests[1].url).to.equal('https://ads.project-limelight.com/hb') - }) - it('Returns valid adUnits', function () { - validateAdUnit(serverRequests[0].data.adUnits[0], bid1) - validateAdUnit(serverRequests[1].data.adUnits[0], bid2) - validateAdUnit(serverRequests[0].data.adUnits[1], bid3) - }) - it('Returns empty data if no valid requests are passed', function () { - const serverRequests = spec.buildRequests([]) - expect(serverRequests).to.be.an('array').that.is.empty - }) - it('Returns request with page field value from ortb2 object if ortb2 has page field', function () { - bidderRequest.ortb2.site = { - page: 'testSitePage' + page: 'https://example.com/page' } - const serverRequests = spec.buildRequests([bid1], bidderRequest) - expect(serverRequests).to.have.lengthOf(1) - serverRequests.forEach(serverRequest => { - expect(serverRequest.data.page).to.be.a('string'); - expect(serverRequest.data.page).to.be.equal('testSitePage'); - }) - }) - }) - describe('interpretBannerResponse', function () { - const resObject = { - body: [ { - requestId: '123', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['example.com'], - mediaType: 'banner' - } - } ] }; - let serverResponses = spec.interpretResponse(resObject); - it('Returns an array of valid server responses if response object is valid', function () { - expect(serverResponses).to.be.an('array').that.is.not.empty; - for (let i = 0; i < serverResponses.length; i++) { - const dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'meta'); - expect(dataItem.requestId).to.be.a('string'); - expect(dataItem.cpm).to.be.a('number'); - expect(dataItem.width).to.be.a('number'); - expect(dataItem.height).to.be.a('number'); - expect(dataItem.ad).to.be.a('string'); - expect(dataItem.ttl).to.be.a('number'); - expect(dataItem.creativeId).to.be.a('string'); - expect(dataItem.netRevenue).to.be.a('boolean'); - expect(dataItem.currency).to.be.a('string'); - expect(dataItem.meta.advertiserDomains).to.be.an('array'); - expect(dataItem.meta.mediaType).to.be.a('string'); + + it('should create two server requests for different hosts', function() { + const serverRequests = spec.buildRequests([bid1, bid2, bid3], bidderRequest); + expect(serverRequests).to.exist; + expect(serverRequests).to.have.lengthOf(2); + }); + + it('should create ServerRequest objects with method, URL and data', function () { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + serverRequests.forEach(serverRequest => { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + }); + + it('should return POST method', function () { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + serverRequests.forEach(serverRequest => { + expect(serverRequest.method).to.equal('POST'); + }); + }); + + it('should return valid OpenRTB request structure', function () { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const data = serverRequests[0].data; + + expect(data).to.be.an('object'); + expect(data).to.have.property('imp'); + expect(data).to.have.property('site'); + expect(data).to.have.property('device'); + expect(data).to.have.property('id'); + expect(data.imp).to.be.an('array'); + }); + + it('should include custom fields in imp.ext', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const imp = serverRequests[0].data.imp[0]; + + expect(deepAccess(imp, 'ext.c1')).to.equal('custom1'); + expect(deepAccess(imp, 'ext.c2')).to.equal('custom2'); + expect(deepAccess(imp, 'ext.c3')).to.equal('custom3'); + expect(deepAccess(imp, 'ext.c4')).to.equal('custom4'); + expect(deepAccess(imp, 'ext.c5')).to.equal('custom5'); + }); + + it('should include adUnitId in imp.ext', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const imp = serverRequests[0].data.imp[0]; + + expect(deepAccess(imp, 'ext.adUnitId')).to.equal(123); + }); + + it('should return valid URLs for different hosts', function () { + const serverRequests = spec.buildRequests([bid1, bid2, bid3], bidderRequest); + + const exchangeRequest = serverRequests.find(req => req.url.includes('exchange.ortb.net')); + const adsRequest = serverRequests.find(req => req.url.includes('ads.project-limelight.com')); + + expect(exchangeRequest.url).to.equal('https://exchange.ortb.net/ortbhb'); + expect(adsRequest.url).to.equal('https://ads.project-limelight.com/ortbhb'); + }); + + it('should group bids by host correctly', function() { + const serverRequests = spec.buildRequests([bid1, bid2, bid3], bidderRequest); + + const exchangeRequest = serverRequests.find(req => req.url.includes('exchange.ortb.net')); + const adsRequest = serverRequests.find(req => req.url.includes('ads.project-limelight.com')); + + expect(exchangeRequest.data.imp).to.have.lengthOf(2); + expect(adsRequest.data.imp).to.have.lengthOf(1); + }); + + it('should return empty array if no valid requests are passed', function () { + const serverRequests = spec.buildRequests([], bidderRequest); + expect(serverRequests).to.be.an('array').that.is.empty; + }); + + it('should include banner format in OpenRTB request', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const imp = serverRequests[0].data.imp[0]; + + expect(imp.banner).to.exist; + expect(imp.banner.format).to.be.an('array'); + expect(imp.banner.format[0]).to.have.property('w', 300); + expect(imp.banner.format[0]).to.have.property('h', 250); + }); + + it('should include video object in OpenRTB request for video bid', function() { + const serverRequests = spec.buildRequests([bid3], bidderRequest); + const imp = serverRequests[0].data.imp[0]; + if (FEATURES.VIDEO) { + expect(imp.video).to.exist; + expect(imp.video).to.be.an('object'); + expect(imp.video.w).to.equal(800); + expect(imp.video.h).to.equal(600); } - it('Returns an empty array if invalid response is passed', function () { - serverResponses = spec.interpretResponse('invalid_response'); - expect(serverResponses).to.be.an('array').that.is.empty; + expect(deepAccess(imp, 'ext.adUnitId')).to.equal(789); + }); + + it('should skip custom fields if they are undefined', function() { + const bidWithoutCustom = { ...bid1, params: { ...bid1.params } }; + delete bidWithoutCustom.params.custom1; + delete bidWithoutCustom.params.custom2; + + const serverRequests = spec.buildRequests([bidWithoutCustom], bidderRequest); + const imp = serverRequests[0].data.imp[0]; + + expect(deepAccess(imp, 'ext.c1')).to.be.undefined; + expect(deepAccess(imp, 'ext.c2')).to.be.undefined; + expect(deepAccess(imp, 'ext.c3')).to.equal('custom3'); + }); + + it('should handle various refererInfo scenarios', function () { + const baseRequest = [{ + bidder: 'limelightDigital', + params: { host: 'exchange.example.com', adUnitId: 'test' }, + mediaTypes: { banner: { sizes: [[300, 250]] } }, + bidId: 'test-bid-id' + }]; + + let requests = spec.buildRequests(baseRequest, { + refererInfo: { page: 'https://test.com' }, + ortb2: {} }); + expect(requests[0].data.site.page).to.equal('https://test.com'); + + requests = spec.buildRequests(baseRequest, { + refererInfo: { page: 'https://referer.com' }, + ortb2: { site: { page: 'https://ortb2.com' } } + }); + expect(requests[0].data.site.page).to.equal('https://ortb2.com'); + + requests = spec.buildRequests(baseRequest, { ortb2: {} }); + expect(requests[0].data.site.page).to.be.undefined; }); - }); - describe('interpretVideoResponse', function () { - const resObject = { - body: [ { - requestId: '123', - cpm: 0.3, - width: 320, - height: 50, - vastXml: '', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['example.com'], - mediaType: 'video' + + describe('buildRequests - size handling', function () { + it('should handle mediaTypes.banner.sizes', function () { + const bidRequests = [{ + bidder: 'limelightDigital', + params: { + host: 'exchange.example.com', + adUnitId: 'test', + adUnitType: 'banner' + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [728, 90]] + } + }, + adUnitCode: 'test-ad-unit', + bidId: 'test-bid-id' + }]; + + const bidderRequest = { + refererInfo: { page: 'https://test.com' }, + ortb2: { site: { domain: 'test.com' } } + }; + + const requests = spec.buildRequests(bidRequests, bidderRequest); + + expect(requests[0].data.imp[0].banner.format).to.deep.equal([ + { w: 300, h: 250 }, + { w: 728, h: 90 } + ]); + }); + + it('should handle legacy sizes without mediaTypes', function () { + const bidRequests = [{ + bidder: 'limelightDigital', + params: { + host: 'exchange.example.com', + adUnitId: 'test', + adUnitType: 'banner' + }, + sizes: [[300, 250], [728, 90]], + adUnitCode: 'test-ad-unit', + bidId: 'test-bid-id' + }]; + + const bidderRequest = { + refererInfo: { page: 'https://test.com' }, + ortb2: { site: { domain: 'test.com' } } + }; + + const requests = spec.buildRequests(bidRequests, bidderRequest); + + expect(requests[0].data.imp[0].banner.format).to.deep.equal([ + { w: 300, h: 250 }, + { w: 728, h: 90 } + ]); + }); + + it('should merge mediaTypes sizes with bidRequest.sizes', function () { + const bidRequests = [{ + bidder: 'limelightDigital', + params: { + host: 'exchange.example.com', + adUnitId: 'test', + adUnitType: 'banner' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + }, + sizes: [[728, 90]], + adUnitCode: 'test-ad-unit', + bidId: 'test-bid-id' + }]; + + const bidderRequest = { + refererInfo: { page: 'https://test.com' }, + ortb2: { site: { domain: 'test.com' } } + }; + + const requests = spec.buildRequests(bidRequests, bidderRequest); + + const formats = requests[0].data.imp[0].banner.format; + expect(formats).to.have.lengthOf(2); + expect(formats).to.deep.include({ w: 300, h: 250 }); + expect(formats).to.deep.include({ w: 728, h: 90 }); + }); + + it('should handle video with playerSize', function () { + const bidRequests = [{ + bidder: 'limelightDigital', + params: { + host: 'exchange.example.com', + adUnitId: 'test', + adUnitType: 'video' + }, + mediaTypes: { + video: { + playerSize: [640, 480] + } + }, + adUnitCode: 'test-ad-unit', + bidId: 'test-bid-id' + }]; + + const bidderRequest = { + refererInfo: { page: 'https://test.com' }, + ortb2: { site: { domain: 'test.com' } } + }; + + const requests = spec.buildRequests(bidRequests, bidderRequest); + if (FEATURES.VIDEO) { + expect(requests[0].data.imp[0].video).to.exist; + expect(requests[0].data.imp[0].video.w).to.equal(640); + expect(requests[0].data.imp[0].video.h).to.equal(480); } - } ] - }; - let serverResponses = spec.interpretResponse(resObject); - it('Returns an array of valid server responses if response object is valid', function () { - expect(serverResponses).to.be.an('array').that.is.not.empty; - for (let i = 0; i < serverResponses.length; i++) { - const dataItem = serverResponses[i]; - expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'vastXml', 'ttl', 'creativeId', - 'netRevenue', 'currency', 'meta'); - expect(dataItem.requestId).to.be.a('string'); - expect(dataItem.cpm).to.be.a('number'); - expect(dataItem.width).to.be.a('number'); - expect(dataItem.height).to.be.a('number'); - expect(dataItem.vastXml).to.be.a('string'); - expect(dataItem.ttl).to.be.a('number'); - expect(dataItem.creativeId).to.be.a('string'); - expect(dataItem.netRevenue).to.be.a('boolean'); - expect(dataItem.currency).to.be.a('string'); - expect(dataItem.meta.advertiserDomains).to.be.an('array'); - expect(dataItem.meta.mediaType).to.be.a('string'); - } - it('should return an empty array if invalid response is passed', function () { - serverResponses = spec.interpretResponse('invalid_response'); - expect(serverResponses).to.be.an('array').that.is.empty; }); }); }); - describe('isBidRequestValid', function() { - const bid = { - bidId: '2dd581a2b6281d', - bidder: 'limelightDigital', - bidderRequestId: '145e1d6a7837c9', - params: { - host: 'exchange.ortb.net', - adUnitId: 123, - adUnitType: 'banner' - }, - placementCode: 'placement_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' + + describe('interpretResponse - Banner', function () { + const bidderRequest = { + ortb2: { + site: { + page: 'https://example.com/page' + } + } }; - it('should return true when required params found', function() { - [bid, bid1, bid2, bid3].forEach(bid => { - expect(spec.isBidRequestValid(bid)).to.equal(true); - }); + it('should return array of valid bid responses', function () { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const ortbResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'bid123', + impid: request.data.imp[0].id, + price: 0.3, + w: 300, + h: 250, + adm: '

Hello ad

', + crid: '123asd', + mtype: 1, + adomain: ['example.com'], + exp: 1000 + }] + }], + cur: 'USD' + } + }; + + const serverResponses = spec.interpretResponse(ortbResponse, request); + + expect(serverResponses).to.be.an('array').that.is.not.empty; + expect(serverResponses).to.have.lengthOf(1); + + const bidResponse = serverResponses[0]; + expect(bidResponse.requestId).to.be.a('string'); + expect(bidResponse.cpm).to.equal(0.3); + expect(bidResponse.width).to.equal(300); + expect(bidResponse.height).to.equal(250); + expect(bidResponse.ad).to.be.a('string'); + expect(bidResponse.ttl).to.be.a('number'); + expect(bidResponse.creativeId).to.be.a('string'); + expect(bidResponse.netRevenue).to.be.a('boolean'); + expect(bidResponse.currency).to.equal('USD'); + expect(bidResponse.mediaType).to.equal('banner'); }); - it('should return true when adUnitId is zero', function() { - bid.params.adUnitId = 0; - expect(spec.isBidRequestValid(bid)).to.equal(true); + it('should return empty array for invalid response', function () { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const serverResponses = spec.interpretResponse({ body: null }, request); + expect(serverResponses).to.be.an('array').that.is.empty; }); - it('should return false when required params are not passed', function() { - const bidFailed = { - bidder: 'limelightDigital', - bidderRequestId: '145e1d6a7837c9', - params: { - adUnitId: 123, - adUnitType: 'banner' - }, - placementCode: 'placement_0', - auctionId: '74f78609-a92d-4cf1-869f-1b244bbfb5d2', - sizes: [[300, 250]], - transactionId: '3bb2f6da-87a6-4029-aeb0-bfe951372e62' + it('should return empty array when response body is missing', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const serverResponses = spec.interpretResponse({}, request); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + + it('should filter out invalid bids', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const invalidResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'bid123', + impid: request.data.imp[0].id, + price: 0.3, + crid: '123asd', + mtype: 1, + adomain: ['example.com'] + }] + }], + cur: 'USD' + } }; - expect(spec.isBidRequestValid(bidFailed)).to.equal(false); + + const serverResponses = spec.interpretResponse(invalidResponse, request); + expect(serverResponses).to.be.an('array').that.is.empty; }); }); - describe('interpretResponse', function() { - const resObject = { - requestId: '123', - cpm: 0.3, - width: 320, - height: 50, - ad: '

Hello ad

', - ttl: 1000, - creativeId: '123asd', - netRevenue: true, - currency: 'USD', - meta: { - advertiserDomains: ['example.com'], - mediaType: 'banner' + + describe('interpretResponse - Video', function () { + const bidderRequest = { + ortb2: { + site: { + page: 'https://example.com/page' + } } }; - it('should skip responses which do not contain required params', function() { - const bidResponses = { - body: [ { - cpm: 0.3, - ttl: 1000, - currency: 'USD', - meta: { - advertiserDomains: ['example.com'], - mediaType: 'banner' - } - }, resObject ] - } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); - }); - it('should skip responses which do not contain advertiser domains', function() { - const resObjectWithoutAdvertiserDomains = Object.assign({}, resObject); - resObjectWithoutAdvertiserDomains.meta = Object.assign({}, resObject.meta); - delete resObjectWithoutAdvertiserDomains.meta.advertiserDomains; - const bidResponses = { - body: [ resObjectWithoutAdvertiserDomains, resObject ] - } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); - }); - it('should return responses which contain empty advertiser domains', function() { - const resObjectWithEmptyAdvertiserDomains = Object.assign({}, resObject); - resObjectWithEmptyAdvertiserDomains.meta = Object.assign({}, resObject.meta); - resObjectWithEmptyAdvertiserDomains.meta.advertiserDomains = []; - const bidResponses = { - body: [ resObjectWithEmptyAdvertiserDomains, resObject ] + + it('should return array of valid video bid responses with mtype', function () { + const serverRequests = spec.buildRequests([bid3], bidderRequest); + const request = serverRequests[0]; + + const ortbResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'bid456', + impid: request.data.imp[0].id, + price: 0.5, + w: 800, + h: 600, + adm: '', + crid: '456def', + mtype: 2, + adomain: ['example.com'] + }] + }], + cur: 'USD' + } + }; + + const serverResponses = spec.interpretResponse(ortbResponse, request); + + expect(serverResponses).to.be.an('array'); + if (serverResponses.length > 0) { + const bidResponse = serverResponses[0]; + expect(bidResponse.mediaType).to.equal('video'); + expect(bidResponse.vastXml).to.be.a('string'); } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([resObjectWithEmptyAdvertiserDomains, resObject]); - }); - it('should skip responses which do not contain meta media type', function() { - const resObjectWithoutMetaMediaType = Object.assign({}, resObject); - resObjectWithoutMetaMediaType.meta = Object.assign({}, resObject.meta); - delete resObjectWithoutMetaMediaType.meta.mediaType; - const bidResponses = { - body: [ resObjectWithoutMetaMediaType, resObject ] + }); + + it('should return array of valid video bid responses with ext.mediaType fallback', function () { + const serverRequests = spec.buildRequests([bid3], bidderRequest); + const request = serverRequests[0]; + + const ortbResponse = { + body: { + seatbid: [{ + bid: [{ + id: 'bid456', + impid: request.data.imp[0].id, + price: 0.5, + w: 800, + h: 600, + adm: '', + crid: '456def', + ext: { + mediaType: 'video' + }, + adomain: ['example.com'] + }] + }], + cur: 'USD' + } + }; + + const serverResponses = spec.interpretResponse(ortbResponse, request); + + expect(serverResponses).to.be.an('array'); + if (serverResponses.length > 0) { + const bidResponse = serverResponses[0]; + expect(bidResponse.mediaType).to.equal('video'); + expect(bidResponse.vastXml).to.be.a('string'); } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); }); }); - describe('getUserSyncs', function () { - it('should return trackers for lm(only iframe) if server responses contain lm user sync header and iframe and image enabled', function () { - const serverResponses = [ - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-lm.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-lm.ortb.net/sync.html'; - } - } - }, - body: [] + + describe('interpretResponse - mediaType fallback', function() { + const bidderRequest = { + ortb2: { + site: { + page: 'https://example.com/page' } - ]; - const syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([ - { - type: 'iframe', - url: 'https://tracker-lm.ortb.net/sync.html' + } + }; + + it('should infer mediaType from imp.banner when mtype is missing', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const responseWithoutMtype = { + body: { + seatbid: [{ + bid: [{ + id: 'bid123', + impid: request.data.imp[0].id, + price: 0.3, + w: 300, + h: 250, + adm: '

Hello ad

', + crid: '123asd', + adomain: ['example.com'], + exp: 1000 + }] + }], + cur: 'USD' } - ]); + }; + + const serverResponses = spec.interpretResponse(responseWithoutMtype, request); + + expect(serverResponses).to.have.lengthOf(1); + expect(serverResponses[0].mediaType).to.equal('banner'); }); - it('should return empty array if all sync types are disabled', function () { - const serverResponses = [ - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-1.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-1.ortb.net/sync.html'; - } - } - }, - body: [] + + it('should use ext.mediaType when available', function() { + const serverRequests = spec.buildRequests([bid1], bidderRequest); + const request = serverRequests[0]; + + const responseWithExtMediaType = { + body: { + seatbid: [{ + bid: [{ + id: 'bid123', + impid: request.data.imp[0].id, + price: 0.3, + w: 300, + h: 250, + adm: '

Hello ad

', + crid: '123asd', + ext: { + mediaType: 'banner' + }, + adomain: ['example.com'], + exp: 1000 + }] + }], + cur: 'USD' } - ]; - const syncOptions = { - iframeEnabled: false, - pixelEnabled: false }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.be.an('array').that.is.empty; + + const serverResponses = spec.interpretResponse(responseWithExtMediaType, request); + + expect(serverResponses).to.have.lengthOf(1); + expect(serverResponses[0].mediaType).to.equal('banner'); }); - it('should return no pixels if iframe sync is enabled and headers are blank', function () { - const serverResponses = [ - { - headers: null, - body: [] - } - ]; - const syncOptions = { - iframeEnabled: true, - pixelEnabled: false + }); + + describe('onBidWon', function() { + it('should replace auction price macro in nurl', function() { + const bid = { + pbMg: 1.23, + nurl: 'https://example.com/win?price=${AUCTION_PRICE}' }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.be.an('array').that.is.empty; + + expect(() => spec.onBidWon(bid)).to.not.throw(); }); - it('should return image sync urls for lm if pixel sync is enabled and headers have lm pixel', function () { - const serverResponses = [ - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-lm.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-lm.ortb.net/sync.html'; - } + + it('should handle empty nurl', function() { + const bid = { + pbMg: 1.23, + nurl: '' + }; + + expect(() => spec.onBidWon(bid)).to.not.throw(); + }); + }); + + describe('getUserSyncs', function () { + it('should return iframe sync when available and enabled', function () { + const serverResponses = [{ + headers: { + get: function (header) { + if (header === 'x-pll-usersync-iframe') { + return 'https://tracker-lm.ortb.net/sync.html'; } - }, - body: [] - } - ]; + if (header === 'x-pll-usersync-image') { + return 'https://tracker-lm.ortb.net/sync'; + } + } + }, + body: {} + }]; + const syncOptions = { - iframeEnabled: false, + iframeEnabled: true, pixelEnabled: true }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([ - { - type: 'image', - url: 'https://tracker-lm.ortb.net/sync' - } - ]); + + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + expect(syncs).to.deep.equal([{ + type: 'iframe', + url: 'https://tracker-lm.ortb.net/sync.html' + }]); }); - it('should return image sync urls for client1 and clien2 if pixel sync is enabled and two responses and headers have two pixels', function () { - const serverResponses = [ - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-1.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-1.ortb.net/sync.html'; - } + + it('should return image sync when iframe not available', function () { + const serverResponses = [{ + headers: { + get: function (header) { + if (header === 'x-pll-usersync-image') { + return 'https://tracker-lm.ortb.net/sync'; } - }, - body: [] + } }, - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-2.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-2.ortb.net/sync.html'; - } - } - }, - body: [] - } - ]; + body: {} + }]; + const syncOptions = { iframeEnabled: false, pixelEnabled: true }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([ - { - type: 'image', - url: 'https://tracker-1.ortb.net/sync' + + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + expect(syncs).to.deep.equal([{ + type: 'image', + url: 'https://tracker-lm.ortb.net/sync' + }]); + }); + + it('should return empty array when all sync types disabled', function () { + const serverResponses = [{ + headers: { + get: function (header) { + return 'https://tracker.ortb.net/sync'; + } }, - { - type: 'image', - url: 'https://tracker-2.ortb.net/sync' - } - ]); + body: {} + }]; + + const syncOptions = { + iframeEnabled: false, + pixelEnabled: false + }; + + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + expect(syncs).to.be.an('array').that.is.empty; }); - it('should return image sync url for pll if pixel sync is enabled and two responses and headers have two same pixels', function () { + + it('should deduplicate sync URLs', function() { const serverResponses = [ { headers: { get: function (header) { if (header === 'x-pll-usersync-image') { - return 'https://tracker-lm.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-lm.ortb.net/sync.html'; + return 'https://tracker.ortb.net/sync'; } } }, - body: [] + body: {} }, { headers: { get: function (header) { if (header === 'x-pll-usersync-image') { - return 'https://tracker-lm.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-lm.ortb.net/sync.html'; + return 'https://tracker.ortb.net/sync'; } } }, - body: [] + body: {} } ]; + const syncOptions = { iframeEnabled: false, pixelEnabled: true }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([ - { - type: 'image', - url: 'https://tracker-lm.ortb.net/sync' - } - ]); - }); - it('should return iframe sync url for pll if pixel sync is enabled and iframe is enables and headers have both iframe and img pixels', function () { - const serverResponses = [ - { - headers: { - get: function (header) { - if (header === 'x-pll-usersync-image') { - return 'https://tracker-lm.ortb.net/sync'; - } - if (header === 'x-pll-usersync-iframe') { - return 'https://tracker-lm.ortb.net/sync.html'; - } - } - }, - body: [] - } - ]; - const syncOptions = { - iframeEnabled: true, - pixelEnabled: true - }; - expect(spec.getUserSyncs(syncOptions, serverResponses)).to.deep.equal([ - { - type: 'iframe', - url: 'https://tracker-lm.ortb.net/sync.html' - } - ]); - }); - }); - describe('getFloor support', function() { - const bidderRequest = { - ortb2: { - device: { - sua: { - browsers: [], - platform: [], - mobile: 1, - architecture: 'arm' - } - } - }, - refererInfo: { - page: 'testPage' - } - }; - it('should include floorInfo when getFloor is available', function() { - const bidWithFloor = { - ...bid1, - getFloor: function(params) { - if (params.size[0] === 300 && params.size[1] === 250) { - return { currency: 'USD', floor: 2.0 }; - } - return { currency: 'USD', floor: 0 }; - } - }; - - const serverRequests = spec.buildRequests([bidWithFloor], bidderRequest); - expect(serverRequests).to.have.lengthOf(1); - const adUnit = serverRequests[0].data.adUnits[0]; - expect(adUnit.sizes).to.have.lengthOf(1); - expect(adUnit.sizes[0].floorInfo).to.exist; - expect(adUnit.sizes[0].floorInfo.currency).to.equal('USD'); - expect(adUnit.sizes[0].floorInfo.floor).to.equal(2.0); - }); - it('should set floorInfo to null when getFloor is not available', function() { - const bidWithoutFloor = { ...bid1 }; - delete bidWithoutFloor.getFloor; - - const serverRequests = spec.buildRequests([bidWithoutFloor], bidderRequest); - expect(serverRequests).to.have.lengthOf(1); - expect(serverRequests[0].data.adUnits[0].sizes[0].floorInfo).to.be.null; - }); - it('should handle multiple sizes with different floors', function() { - const bidWithMultipleSizes = { - ...bid1, - mediaTypes: { - banner: { - sizes: [[300, 250], [728, 90]] - } - }, - getFloor: function(params) { - if (params.size[0] === 300 && params.size[1] === 250) { - return { currency: 'USD', floor: 1.5 }; - } - if (params.size[0] === 728 && params.size[1] === 90) { - return { currency: 'USD', floor: 2.0 }; - } - return { currency: 'USD', floor: 0 }; - } - }; - - const serverRequests = spec.buildRequests([bidWithMultipleSizes], bidderRequest); - expect(serverRequests).to.have.lengthOf(1); - const adUnit = serverRequests[0].data.adUnits[0]; - expect(adUnit.sizes).to.have.lengthOf(2); - expect(adUnit.sizes[0].floorInfo.floor).to.equal(1.5); - expect(adUnit.sizes[1].floorInfo.floor).to.equal(2.0); - }); - it('should set floorInfo to null when getFloor returns empty object', function() { - const bidWithEmptyFloor = { - ...bid1, - getFloor: function() { - return {}; - } - }; - - const serverRequests = spec.buildRequests([bidWithEmptyFloor], bidderRequest); - expect(serverRequests).to.have.lengthOf(1); - expect(serverRequests[0].data.adUnits[0].sizes[0].floorInfo).to.deep.equal({}); - }); - it('should handle getFloor errors and set floorInfo to null', function() { - const bidWithErrorFloor = { - ...bid1, - getFloor: function() { - throw new Error('Floor module error'); - } - }; - const serverRequests = spec.buildRequests([bidWithErrorFloor], bidderRequest); - expect(serverRequests).to.have.lengthOf(1); - const adUnit = serverRequests[0].data.adUnits[0]; - expect(adUnit.sizes[0].floorInfo).to.be.null; + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + expect(syncs).to.have.lengthOf(1); }); }); }); - -function validateAdUnit(adUnit, bid) { - expect(adUnit.id).to.equal(bid.params.adUnitId); - expect(adUnit.bidId).to.equal(bid.bidId); - expect(adUnit.type).to.equal(bid.params.adUnitType.toUpperCase()); - expect(adUnit.transactionId).to.equal(bid.ortb2Imp.ext.tid); - let bidSizes = []; - if (bid.mediaTypes) { - if (bid.mediaTypes.video && bid.mediaTypes.video.playerSize) { - bidSizes = bidSizes.concat([bid.mediaTypes.video.playerSize]); - } - if (bid.mediaTypes.banner && bid.mediaTypes.banner.sizes) { - bidSizes = bidSizes.concat(bid.mediaTypes.banner.sizes); - } - } - if (bid.sizes) { - bidSizes = bidSizes.concat(bid.sizes || []); - } - expect(adUnit.sizes).to.deep.equal(bidSizes.map(size => { - return { - width: size[0], - height: size[1], - floorInfo: null - } - })); - expect(adUnit.publisherId).to.equal(bid.params.publisherId); - expect(adUnit.userIdAsEids).to.deep.equal(bid.userIdAsEids); - expect(adUnit.supplyChain).to.deep.equal(bid.ortb2.source.ext.schain); - expect(adUnit.ortb2Imp).to.deep.equal(bid.ortb2Imp); -} diff --git a/test/spec/modules/liveIntentAnalyticsAdapter_spec.js b/test/spec/modules/liveIntentAnalyticsAdapter_spec.js index 869e9eb789c..65a363432a3 100644 --- a/test/spec/modules/liveIntentAnalyticsAdapter_spec.js +++ b/test/spec/modules/liveIntentAnalyticsAdapter_spec.js @@ -57,8 +57,8 @@ describe('LiveIntent Analytics Adapter ', () => { sandbox.stub(events, 'getEvents').returns([]); sandbox.stub(config, 'getConfig').withArgs('userSync.userIds').returns(USERID_CONFIG); sandbox.stub(utils, 'generateUUID').returns(instanceId); - sandbox.stub(refererDetection, 'getRefererInfo').returns({page: url}); - sandbox.stub(auctionManager.index, 'getAuction').withArgs({auctionId: AUCTION_INIT_EVENT.auctionId}).returns({ + sandbox.stub(refererDetection, 'getRefererInfo').returns({ page: url }); + sandbox.stub(auctionManager.index, 'getAuction').withArgs({ auctionId: AUCTION_INIT_EVENT.auctionId }).returns({ getBidRequests: () => AUCTION_INIT_EVENT.bidderRequests, getAuctionStart: () => AUCTION_INIT_EVENT.timestamp }); diff --git a/test/spec/modules/liveIntentExternalIdSystem_spec.js b/test/spec/modules/liveIntentExternalIdSystem_spec.js index c4bd7eec960..c9569c44dbb 100644 --- a/test/spec/modules/liveIntentExternalIdSystem_spec.js +++ b/test/spec/modules/liveIntentExternalIdSystem_spec.js @@ -4,7 +4,7 @@ import { gdprDataHandler, uspDataHandler, gppDataHandler, coppaDataHandler } fro import * as refererDetection from '../../../src/refererDetection.js'; const DEFAULT_AJAX_TIMEOUT = 5000 const PUBLISHER_ID = '89899'; -const defaultConfigParams = { params: {publisherId: PUBLISHER_ID, fireEventDelay: 1} }; +const defaultConfigParams = { params: { publisherId: PUBLISHER_ID, fireEventDelay: 1 } }; describe('LiveIntentExternalId', function() { let uspConsentDataStub; @@ -100,16 +100,18 @@ describe('LiveIntentExternalId', function() { expect(resolveCommand).to.eql({ clientRef: {}, onSuccess: [{ type: 'callback' }], - requestedAttributes: [ 'nonId' ], + requestedAttributes: ['nonId'], type: 'resolve' }) }); it('should fire an event when getId and a hash is provided', function() { - liveIntentExternalIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - emailHash: '58131bc547fb87af94cebdaf3102321f' - }}).callback(() => {}); + liveIntentExternalIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + emailHash: '58131bc547fb87af94cebdaf3102321f' + } + }).callback(() => {}); expect(window.liQHub).to.have.length(3) @@ -138,7 +140,7 @@ describe('LiveIntentExternalId', function() { expect(resolveCommand).to.eql({ clientRef: {}, onSuccess: [{ type: 'callback' }], - requestedAttributes: [ 'nonId' ], + requestedAttributes: ['nonId'], type: 'resolve' }) }); @@ -277,19 +279,21 @@ describe('LiveIntentExternalId', function() { it('should decode a unifiedId to lipbId and remove it', function() { const result = liveIntentExternalIdSubmodule.decode({ unifiedId: 'data' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data' } }); }); it('should decode a nonId to lipbId', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'data' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'data', 'nonId': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data', 'nonId': 'data' } }); }); it('should resolve extra attributes', function() { - liveIntentExternalIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } - } }).callback(() => {}); + liveIntentExternalIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } + } + }).callback(() => {}); expect(window.liQHub).to.have.length(2) expect(window.liQHub[0]).to.eql({ @@ -312,73 +316,75 @@ describe('LiveIntentExternalId', function() { expect(resolveCommand).to.eql({ clientRef: {}, onSuccess: [{ type: 'callback' }], - requestedAttributes: [ 'nonId', 'foo' ], + requestedAttributes: ['nonId', 'foo'], type: 'resolve' }) }); it('should decode values with the segments but no nonId', function() { - const result = liveIntentExternalIdSubmodule.decode({segments: ['tak']}, defaultConfigParams); - expect(result).to.eql({'lipb': {'segments': ['tak']}}); + const result = liveIntentExternalIdSubmodule.decode({ segments: ['tak'] }, defaultConfigParams); + expect(result).to.eql({ 'lipb': { 'segments': ['tak'] } }); }); it('should decode a uid2 to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', uid2: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode values with uid2 but no nonId', function() { const result = liveIntentExternalIdSubmodule.decode({ uid2: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a bidswitch id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', bidswitch: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar'}, 'bidswitch': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar' }, 'bidswitch': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a medianet id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', medianet: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar'}, 'medianet': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar' }, 'medianet': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sovrn id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', sovrn: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar'}, 'sovrn': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar' }, 'sovrn': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a magnite id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', magnite: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar'}, 'magnite': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar' }, 'magnite': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an index id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', index: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar'}, 'index': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar' }, 'index': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an openx id to a separate object when present', function () { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', openx: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar'}, 'openx': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar' }, 'openx': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an pubmatic id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', pubmatic: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar'}, 'pubmatic': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar' }, 'pubmatic': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a thetradedesk id to a separate object when present', function() { const provider = 'liveintent.com' - refererInfoStub.returns({domain: provider}) + refererInfoStub.returns({ domain: provider }) const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', thetradedesk: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar'}, 'tdid': {'id': 'bar', 'ext': {'rtiPartner': 'TDID', 'provider': provider}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar' }, 'tdid': { 'id': 'bar', 'ext': { 'rtiPartner': 'TDID', 'provider': provider } } }); }); it('should allow disabling nonId resolution', function() { - liveIntentExternalIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } - } }).callback(() => {}); + liveIntentExternalIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } + } + }).callback(() => {}); expect(window.liQHub).to.have.length(2) expect(window.liQHub[0]).to.eql({ @@ -400,44 +406,44 @@ describe('LiveIntentExternalId', function() { expect(resolveCommand).to.eql({ clientRef: {}, onSuccess: [{ type: 'callback' }], - requestedAttributes: [ 'uid2' ], + requestedAttributes: ['uid2'], type: 'resolve' }) }); it('should decode a sharethrough id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', sharethrough: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar'}, 'sharethrough': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar' }, 'sharethrough': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sonobi id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', sonobi: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar'}, 'sonobi': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar' }, 'sonobi': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a triplelift id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', triplelift: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'triplelift': 'bar'}, 'triplelift': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'triplelift': 'bar' }, 'triplelift': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a zetassp id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', zetassp: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar'}, 'zetassp': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar' }, 'zetassp': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a nexxen id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', nexxen: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar'}, 'nexxen': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar' }, 'nexxen': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a vidazoo id to a separate object when present', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar'}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar' }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode the segments as part of lipb', function() { const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', 'segments': ['bar'] }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar']}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar'] } }); }); it('getId does not set the global variables when liModuleEnabled, liTreatmentRate and activatePartialTreatment are undefined', function() { @@ -520,7 +526,7 @@ describe('LiveIntentExternalId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: undefined } }; const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.be.undefined }); @@ -531,7 +537,7 @@ describe('LiveIntentExternalId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: undefined } }; const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.eq(0.7) }); @@ -542,7 +548,7 @@ describe('LiveIntentExternalId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: false } }; const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.eq(0.7) }); @@ -554,7 +560,7 @@ describe('LiveIntentExternalId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: true } }; const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.eq(true) expect(window.liTreatmentRate).to.eq(0.7) }); @@ -613,7 +619,7 @@ describe('LiveIntentExternalId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: true } }; const result = liveIntentExternalIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.eq(true) expect(window.liTreatmentRate).to.eq(DEFAULT_TREATMENT_RATE) }); diff --git a/test/spec/modules/liveIntentIdMinimalSystem_spec.js b/test/spec/modules/liveIntentIdMinimalSystem_spec.js index c7bbe040986..eb2f93396dd 100644 --- a/test/spec/modules/liveIntentIdMinimalSystem_spec.js +++ b/test/spec/modules/liveIntentIdMinimalSystem_spec.js @@ -5,8 +5,8 @@ import { liveIntentIdSubmodule, reset as resetLiveIntentIdSubmodule, storage } f import * as refererDetection from '../../../src/refererDetection.js'; const PUBLISHER_ID = '89899'; -const defaultConfigParams = { params: {publisherId: PUBLISHER_ID} }; -const responseHeader = {'Content-Type': 'application/json'}; +const defaultConfigParams = { params: { publisherId: PUBLISHER_ID } }; +const responseHeader = { 'Content-Type': 'application/json' }; describe('LiveIntentMinimalId', function() { let logErrorStub; @@ -60,7 +60,7 @@ describe('LiveIntentMinimalId', function() { it('should call the Custom URL of the LiveIntent Identity Exchange endpoint', function() { getCookieStub.returns(null); const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: {...defaultConfigParams.params, ...{'url': 'https://dummy.liveintent.com/idex'}} }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ params: { ...defaultConfigParams.params, ...{ 'url': 'https://dummy.liveintent.com/idex' } } }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/prebid/89899?resolve=nonId'); @@ -103,13 +103,15 @@ describe('LiveIntentMinimalId', function() { it('should call the default url of the LiveIntent Identity Exchange endpoint, with a partner', function() { getCookieStub.returns(null); const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ - 'url': 'https://dummy.liveintent.com/idex', - 'partner': 'rubicon' + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ + 'url': 'https://dummy.liveintent.com/idex', + 'partner': 'rubicon' + } } - } }).callback; + }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq('https://dummy.liveintent.com/idex/rubicon/89899?resolve=nonId'); @@ -172,12 +174,14 @@ describe('LiveIntentMinimalId', function() { const oldCookie = 'a-xxxx--123e4567-e89b-12d3-a456-426655440000' getDataFromLocalStorageStub.withArgs('_li_duid').returns(oldCookie); getDataFromLocalStorageStub.withArgs('_thirdPC').returns('third-pc'); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] + const configParams = { + params: { + ...defaultConfigParams.params, + ...{ + 'identifiersToResolve': ['_thirdPC'] + } } - }}; + }; const callBackSpy = sinon.spy(); const submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); @@ -193,13 +197,15 @@ describe('LiveIntentMinimalId', function() { it('should include an additional identifier value to resolve even if it is an object', function() { getCookieStub.returns(null); - getDataFromLocalStorageStub.withArgs('_thirdPC').returns({'key': 'value'}); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] + getDataFromLocalStorageStub.withArgs('_thirdPC').returns({ 'key': 'value' }); + const configParams = { + params: { + ...defaultConfigParams.params, + ...{ + 'identifiersToResolve': ['_thirdPC'] + } } - }}; + }; const callBackSpy = sinon.spy(); const submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); @@ -215,20 +221,22 @@ describe('LiveIntentMinimalId', function() { it('should decode a unifiedId to lipbId and remove it', function() { const result = liveIntentIdSubmodule.decode({ unifiedId: 'data' }); - expect(result).to.eql({'lipb': {'lipbid': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data' } }); }); it('should decode a nonId to lipbId', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'data' }); - expect(result).to.eql({'lipb': {'lipbid': 'data', 'nonId': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data', 'nonId': 'data' } }); }); it('should resolve extra attributes', function() { const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } - } }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } + } + }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?resolve=nonId&resolve=foo`); @@ -241,68 +249,70 @@ describe('LiveIntentMinimalId', function() { }); it('should decode values with the segments but no nonId', function() { - const result = liveIntentIdSubmodule.decode({segments: ['tak']}, { params: defaultConfigParams }); - expect(result).to.eql({'lipb': {'segments': ['tak']}}); + const result = liveIntentIdSubmodule.decode({ segments: ['tak'] }, { params: defaultConfigParams }); + expect(result).to.eql({ 'lipb': { 'segments': ['tak'] } }); }); it('should decode a uid2 to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', uid2: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode values with uid2 but no nonId', function() { const result = liveIntentIdSubmodule.decode({ uid2: 'bar' }); - expect(result).to.eql({'lipb': {'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a bidswitch id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', bidswitch: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar'}, 'bidswitch': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar' }, 'bidswitch': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a medianet id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', medianet: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar'}, 'medianet': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar' }, 'medianet': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sovrn id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sovrn: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar'}, 'sovrn': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar' }, 'sovrn': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a magnite id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', magnite: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar'}, 'magnite': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar' }, 'magnite': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an index id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', index: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar'}, 'index': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar' }, 'index': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an openx id to a separate object when present', function () { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', openx: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar'}, 'openx': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar' }, 'openx': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an pubmatic id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', pubmatic: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar'}, 'pubmatic': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar' }, 'pubmatic': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a thetradedesk id to a separate object when present', function() { const provider = 'liveintent.com' - refererInfoStub.returns({domain: provider}) + refererInfoStub.returns({ domain: provider }) const result = liveIntentIdSubmodule.decode({ nonId: 'foo', thetradedesk: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar'}, 'tdid': {'id': 'bar', 'ext': {'rtiPartner': 'TDID', 'provider': provider}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar' }, 'tdid': { 'id': 'bar', 'ext': { 'rtiPartner': 'TDID', 'provider': provider } } }); }); it('should allow disabling nonId resolution', function() { const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } - } }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } + } + }).callback; submoduleCallback(callBackSpy); const request = server.requests[0]; expect(request.url).to.be.eq(`https://idx.liadm.com/idex/prebid/89899?resolve=uid2`); @@ -316,31 +326,31 @@ describe('LiveIntentMinimalId', function() { it('should decode a sharethrough id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sharethrough: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar'}, 'sharethrough': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar' }, 'sharethrough': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sonobi id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sonobi: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar'}, 'sonobi': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar' }, 'sonobi': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a zetassp id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', zetassp: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar'}, 'zetassp': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar' }, 'zetassp': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a vidazoo id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar'}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar' }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a nexxen id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', nexxen: 'bar' }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar'}, 'nexxen': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar' }, 'nexxen': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode the segments as part of lipb', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', 'segments': ['bar'] }, { params: defaultConfigParams }); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar']}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar'] } }); }); }); diff --git a/test/spec/modules/liveIntentIdSystem_spec.js b/test/spec/modules/liveIntentIdSystem_spec.js index ecf7dc9a634..e6ce3a6cca2 100644 --- a/test/spec/modules/liveIntentIdSystem_spec.js +++ b/test/spec/modules/liveIntentIdSystem_spec.js @@ -4,14 +4,14 @@ import { DEFAULT_TREATMENT_RATE } from 'libraries/liveIntentId/shared.js'; import { gdprDataHandler, uspDataHandler, gppDataHandler, coppaDataHandler } from '../../../src/adapterManager.js'; import { server } from 'test/mocks/xhr.js'; import * as refererDetection from '../../../src/refererDetection.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; resetLiveIntentIdSubmodule(); liveIntentIdSubmodule.setModuleMode('standard') const PUBLISHER_ID = '89899'; const defaultConfigParams = { params: { publisherId: PUBLISHER_ID, fireEventDelay: 1 } }; -const responseHeader = {'Content-Type': 'application/json'} +const responseHeader = { 'Content-Type': 'application/json' } function requests(...urlRegExps) { return server.requests.filter((request) => urlRegExps.some((regExp) => request.url.match(regExp))) @@ -107,10 +107,12 @@ describe('LiveIntentId', function() { }); it('should fire an event when getId and a hash is provided', function(done) { - liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - emailHash: '58131bc547fb87af94cebdaf3102321f' - }}); + liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + emailHash: '58131bc547fb87af94cebdaf3102321f' + } + }); setTimeout(() => { const request = rpRequests()[0]; expect(request.url).to.match(/https:\/\/rp.liadm.com\/j\?.*e=58131bc547fb87af94cebdaf3102321f.+/) @@ -128,16 +130,18 @@ describe('LiveIntentId', function() { }); it('should initialize LiveConnect with the config params when decode and emit an event', function (done) { - liveIntentIdSubmodule.decode({}, { params: { - ...defaultConfigParams.params, - ...{ - url: 'https://dummy.liveintent.com', - liCollectConfig: { - appId: 'a-0001', - collectorUrl: 'https://collector.liveintent.com' + liveIntentIdSubmodule.decode({}, { + params: { + ...defaultConfigParams.params, + ...{ + url: 'https://dummy.liveintent.com', + liCollectConfig: { + appId: 'a-0001', + collectorUrl: 'https://collector.liveintent.com' + } } } - }}); + }); setTimeout(() => { const request = requests(/https:\/\/collector.liveintent.com\/j\?.*aid=a-0001.*&wpn=prebid.*/); expect(request.length).to.be.greaterThan(0); @@ -183,10 +187,12 @@ describe('LiveIntentId', function() { }); it('should fire an event when decode and a hash is provided', function(done) { - liveIntentIdSubmodule.decode({}, { params: { - ...defaultConfigParams.params, - emailHash: '58131bc547fb87af94cebdaf3102321f' - }}); + liveIntentIdSubmodule.decode({}, { + params: { + ...defaultConfigParams.params, + emailHash: '58131bc547fb87af94cebdaf3102321f' + } + }); setTimeout(() => { const request = rpRequests()[0]; expect(request.url).to.match(/https:\/\/rp.liadm.com\/j\?.*e=58131bc547fb87af94cebdaf3102321f.+/); @@ -216,7 +222,7 @@ describe('LiveIntentId', function() { it('should call the custom URL of the LiveIntent Identity Exchange endpoint', function() { getCookieStub.returns(null); const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: {...defaultConfigParams.params, ...{'url': 'https://dummy.liveintent.com/idex'}} }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ params: { ...defaultConfigParams.params, ...{ 'url': 'https://dummy.liveintent.com/idex' } } }).callback; submoduleCallback(callBackSpy); const request = requests(/https:\/\/dummy.liveintent.com\/idex\/.*/)[0]; expect(request.url).to.match(/https:\/\/dummy.liveintent.com\/idex\/prebid\/89899\?.*cd=.localhost.*&resolve=nonId.*/); @@ -258,13 +264,15 @@ describe('LiveIntentId', function() { it('should call the default url of the LiveIntent Identity Exchange endpoint, with a partner', function() { getCookieStub.returns(null); const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ - 'url': 'https://dummy.liveintent.com/idex', - 'partner': 'rubicon' + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ + 'url': 'https://dummy.liveintent.com/idex', + 'partner': 'rubicon' + } } - } }).callback; + }).callback; submoduleCallback(callBackSpy); const request = requests(/https:\/\/dummy.liveintent.com\/idex\/.*/)[0]; expect(request.url).to.match(/https:\/\/dummy.liveintent.com\/idex\/rubicon\/89899\?.*cd=.localhost.*&resolve=nonId.*/); @@ -328,12 +336,14 @@ describe('LiveIntentId', function() { const oldCookie = 'a-xxxx--123e4567-e89b-12d3-a456-426655440000' getCookieStub.withArgs('_lc2_fpi').returns(oldCookie); getDataFromLocalStorageStub.withArgs('_thirdPC').returns('third-pc'); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] + const configParams = { + params: { + ...defaultConfigParams.params, + ...{ + 'identifiersToResolve': ['_thirdPC'] + } } - }}; + }; const callBackSpy = sinon.spy(); const submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); @@ -350,13 +360,15 @@ describe('LiveIntentId', function() { it('should include an additional identifier value to resolve even if it is an object', function() { getCookieStub.returns(null); - getDataFromLocalStorageStub.withArgs('_thirdPC').returns({'key': 'value'}); - const configParams = { params: { - ...defaultConfigParams.params, - ...{ - 'identifiersToResolve': ['_thirdPC'] + getDataFromLocalStorageStub.withArgs('_thirdPC').returns({ 'key': 'value' }); + const configParams = { + params: { + ...defaultConfigParams.params, + ...{ + 'identifiersToResolve': ['_thirdPC'] + } } - }}; + }; const callBackSpy = sinon.spy(); const submoduleCallback = liveIntentIdSubmodule.getId(configParams).callback; submoduleCallback(callBackSpy); @@ -371,12 +383,14 @@ describe('LiveIntentId', function() { }); it('should include ip4,ip6,userAgent if it\'s present', function(done) { - liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ipv4: 'foov4', - ipv6: 'foov6', - userAgent: 'boo' - }}); + liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ipv4: 'foov4', + ipv6: 'foov6', + userAgent: 'boo' + } + }); setTimeout(() => { const request = rpRequests()[0]; expect(request.url).to.match(/^https:\/\/rp\.liadm\.com\/j?.*pip=.*&pip6=.*$/) @@ -393,20 +407,22 @@ describe('LiveIntentId', function() { it('should decode a unifiedId to lipbId and remove it', function() { const result = liveIntentIdSubmodule.decode({ unifiedId: 'data' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data' } }); }); it('should decode a nonId to lipbId', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'data' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'data', 'nonId': 'data'}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'data', 'nonId': 'data' } }); }); it('should resolve extra attributes', function() { const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } - } }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'foo': true, 'bar': false } } + } + }).callback; submoduleCallback(callBackSpy); const request = idxRequests()[0]; expect(request.url).to.match(/https:\/\/idx.liadm.com\/idex\/prebid\/89899\?.*cd=.localhost.*&resolve=nonId.*&resolve=foo.*/); @@ -420,72 +436,74 @@ describe('LiveIntentId', function() { it('should decode a uid2 to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', uid2: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode values with the segments but no nonId', function() { - const result = liveIntentIdSubmodule.decode({segments: ['tak']}, defaultConfigParams); - expect(result).to.eql({'lipb': {'segments': ['tak']}}); + const result = liveIntentIdSubmodule.decode({ segments: ['tak'] }, defaultConfigParams); + expect(result).to.eql({ 'lipb': { 'segments': ['tak'] } }); }); it('should decode values with uid2 but no nonId', function() { const result = liveIntentIdSubmodule.decode({ uid2: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'uid2': 'bar'}, 'uid2': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'uid2': 'bar' }, 'uid2': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a bidswitch id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', bidswitch: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar'}, 'bidswitch': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'bidswitch': 'bar' }, 'bidswitch': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a medianet id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', medianet: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar'}, 'medianet': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'medianet': 'bar' }, 'medianet': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sovrn id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sovrn: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar'}, 'sovrn': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sovrn': 'bar' }, 'sovrn': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a magnite id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', magnite: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar'}, 'magnite': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'magnite': 'bar' }, 'magnite': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an index id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', index: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar'}, 'index': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'index': 'bar' }, 'index': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an openx id to a separate object when present', function () { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', openx: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar'}, 'openx': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'openx': 'bar' }, 'openx': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode an pubmatic id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', pubmatic: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar'}, 'pubmatic': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'pubmatic': 'bar' }, 'pubmatic': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a thetradedesk id to a separate object when present', function() { const provider = 'liveintent.com' - refererInfoStub.returns({domain: provider}) + refererInfoStub.returns({ domain: provider }) const result = liveIntentIdSubmodule.decode({ nonId: 'foo', thetradedesk: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar'}, 'tdid': {'id': 'bar', 'ext': {'rtiPartner': 'TDID', 'provider': provider}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'tdid': 'bar' }, 'tdid': { 'id': 'bar', 'ext': { 'rtiPartner': 'TDID', 'provider': provider } } }); }); it('should decode the segments as part of lipb', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', 'segments': ['bar'] }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar']}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'segments': ['bar'] } }); }); it('should allow disabling nonId resolution', function() { const callBackSpy = sinon.spy(); - const submoduleCallback = liveIntentIdSubmodule.getId({ params: { - ...defaultConfigParams.params, - ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } - } }).callback; + const submoduleCallback = liveIntentIdSubmodule.getId({ + params: { + ...defaultConfigParams.params, + ...{ requestedAttributesOverrides: { 'nonId': false, 'uid2': true } } + } + }).callback; submoduleCallback(callBackSpy); const request = idxRequests()[0]; expect(request.url).to.match(/https:\/\/idx.liadm.com\/idex\/prebid\/89899\?.*cd=.localhost.*&resolve=uid2.*/); @@ -499,32 +517,32 @@ describe('LiveIntentId', function() { it('should decode a sharethrough id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sharethrough: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar'}, 'sharethrough': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sharethrough': 'bar' }, 'sharethrough': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a sonobi id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', sonobi: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar'}, 'sonobi': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'sonobi': 'bar' }, 'sonobi': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a triplelift id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', triplelift: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'triplelift': 'bar'}, 'triplelift': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'triplelift': 'bar' }, 'triplelift': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a zetassp id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', zetassp: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar'}, 'zetassp': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'zetassp': 'bar' }, 'zetassp': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a nexxen id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', nexxen: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar'}, 'nexxen': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'nexxen': 'bar' }, 'nexxen': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('should decode a vidazoo id to a separate object when present', function() { const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar' }, defaultConfigParams); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar'}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar' }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); }); it('getId does not set the global variables when liModuleEnabled, liTreatmentRate and activatePartialTreatment are undefined', function() { @@ -607,7 +625,7 @@ describe('LiveIntentId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: undefined } }; const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.be.undefined }); @@ -618,7 +636,7 @@ describe('LiveIntentId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: undefined } }; const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.eq(0.7) }); @@ -629,7 +647,7 @@ describe('LiveIntentId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: false } }; const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.be.undefined expect(window.liTreatmentRate).to.eq(0.7) }); @@ -641,7 +659,7 @@ describe('LiveIntentId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: true } }; const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.eq(true) expect(window.liTreatmentRate).to.eq(0.7) }); @@ -700,7 +718,7 @@ describe('LiveIntentId', function() { const configWithPartialTreatment = { params: { ...defaultConfigParams.params, activatePartialTreatment: true } }; const result = liveIntentIdSubmodule.decode({ nonId: 'foo', vidazoo: 'bar', segments: ['tak'] }, configWithPartialTreatment); - expect(result).to.eql({'lipb': {'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak']}, 'vidazoo': {'id': 'bar', 'ext': {'provider': 'liveintent.com'}}}); + expect(result).to.eql({ 'lipb': { 'lipbid': 'foo', 'nonId': 'foo', 'vidazoo': 'bar', 'segments': ['tak'] }, 'vidazoo': { 'id': 'bar', 'ext': { 'provider': 'liveintent.com' } } }); expect(window.liModuleEnabled).to.eq(true) expect(window.liTreatmentRate).to.eq(DEFAULT_TREATMENT_RATE) }); @@ -720,8 +738,8 @@ describe('LiveIntentId', function() { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'liveintent.com', - uids: [{id: 'some-random-id-value', atype: 3}], - ext: {segments: ['s1', 's2']} + uids: [{ id: 'some-random-id-value', atype: 3 }], + ext: { segments: ['s1', 's2'] } }); }); it('fpid; getValue call', function() { @@ -734,12 +752,12 @@ describe('LiveIntentId', function() { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'fpid.liveintent.com', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); it('bidswitch', function() { const userId = { - bidswitch: {'id': 'sample_id'} + bidswitch: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -754,7 +772,7 @@ describe('LiveIntentId', function() { it('bidswitch with ext', function() { const userId = { - bidswitch: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + bidswitch: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -771,7 +789,7 @@ describe('LiveIntentId', function() { }); it('medianet', function() { const userId = { - medianet: {'id': 'sample_id'} + medianet: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -786,7 +804,7 @@ describe('LiveIntentId', function() { it('medianet with ext', function() { const userId = { - medianet: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + medianet: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -804,7 +822,7 @@ describe('LiveIntentId', function() { it('sovrn', function() { const userId = { - sovrn: {'id': 'sample_id'} + sovrn: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -819,7 +837,7 @@ describe('LiveIntentId', function() { it('sovrn with ext', function() { const userId = { - sovrn: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + sovrn: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -837,7 +855,7 @@ describe('LiveIntentId', function() { it('magnite', function() { const userId = { - magnite: {'id': 'sample_id'} + magnite: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -852,7 +870,7 @@ describe('LiveIntentId', function() { it('magnite with ext', function() { const userId = { - magnite: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + magnite: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -869,7 +887,7 @@ describe('LiveIntentId', function() { }); it('index', function() { const userId = { - index: {'id': 'sample_id'} + index: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -884,7 +902,7 @@ describe('LiveIntentId', function() { it('index with ext', function() { const userId = { - index: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + index: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -935,7 +953,7 @@ describe('LiveIntentId', function() { it('pubmatic', function() { const userId = { - pubmatic: {'id': 'sample_id'} + pubmatic: { 'id': 'sample_id' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -950,7 +968,7 @@ describe('LiveIntentId', function() { it('pubmatic with ext', function() { const userId = { - pubmatic: {'id': 'sample_id', 'ext': {'provider': 'some.provider.com'}} + pubmatic: { 'id': 'sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -976,7 +994,7 @@ describe('LiveIntentId', function() { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'liveintent.com', - uids: [{id: 'some-random-id-value', atype: 3}] + uids: [{ id: 'some-random-id-value', atype: 3 }] }); }); diff --git a/test/spec/modules/liveIntentRtdProvider_spec.js b/test/spec/modules/liveIntentRtdProvider_spec.js index bde3e48b692..2b8ac0cee0e 100644 --- a/test/spec/modules/liveIntentRtdProvider_spec.js +++ b/test/spec/modules/liveIntentRtdProvider_spec.js @@ -1,4 +1,4 @@ -import {liveIntentRtdSubmodule} from 'modules/liveIntentRtdProvider.js'; +import { liveIntentRtdSubmodule } from 'modules/liveIntentRtdProvider.js'; import * as utils from 'src/utils.js'; import { expect } from 'chai'; @@ -63,7 +63,7 @@ describe('LiveIntent Rtd Provider', function () { liveIntentRtdSubmodule.onBidRequestEvent(bidRequest); const ortb2 = bidRequest.bids[0].ortb2; - const expectedOrtb2 = {user: {data: [{name: 'liveintent.com', segment: [{id: 'asa_1231'}, {id: 'lalo_4311'}, {id: 'liurl_99123'}]}]}} + const expectedOrtb2 = { user: { data: [{ name: 'liveintent.com', segment: [{ id: 'asa_1231' }, { id: 'lalo_4311' }, { id: 'liurl_99123' }] }] } } expect(ortb2).to.deep.equal(expectedOrtb2); }); @@ -73,7 +73,7 @@ describe('LiveIntent Rtd Provider', function () { liveIntentRtdSubmodule.onBidRequestEvent(bidRequest); const ortb2 = bidRequest.bids[0].ortb2; - const expectedOrtb2 = {source: {}, user: {data: [{name: 'liveintent.com', segment: [{id: 'asa_1231'}, {id: 'lalo_4311'}, {id: 'liurl_99123'}]}]}} + const expectedOrtb2 = { source: {}, user: { data: [{ name: 'liveintent.com', segment: [{ id: 'asa_1231' }, { id: 'lalo_4311' }, { id: 'liurl_99123' }] }] } } expect(ortb2).to.deep.equal(expectedOrtb2); }); @@ -86,7 +86,7 @@ describe('LiveIntent Rtd Provider', function () { liveIntentRtdSubmodule.onBidRequestEvent(bidRequest); const ortb2 = bidRequest.bids[0].ortb2; - const expectedOrtb2 = {source: {}, user: {data: [{name: 'liveintent.com', segment: [{id: 'asa_1231'}, {id: 'lalo_4311'}, {id: 'liurl_99123'}]}]}} + const expectedOrtb2 = { source: {}, user: { data: [{ name: 'liveintent.com', segment: [{ id: 'asa_1231' }, { id: 'lalo_4311' }, { id: 'liurl_99123' }] }] } } expect(ortb2).to.deep.equal(expectedOrtb2); }); @@ -109,7 +109,7 @@ describe('LiveIntent Rtd Provider', function () { liveIntentRtdSubmodule.onBidRequestEvent(bidRequest); const ortb2 = bidRequest.bids[0].ortb2; - const expectedOrtb2 = {source: {}, user: {data: [{name: 'example.com', segment: [{id: 'a_1231'}, {id: 'b_4311'}]}, {name: 'liveintent.com', segment: [{id: 'asa_1231'}, {id: 'lalo_4311'}, {id: 'liurl_99123'}]}]}} + const expectedOrtb2 = { source: {}, user: { data: [{ name: 'example.com', segment: [{ id: 'a_1231' }, { id: 'b_4311' }] }, { name: 'liveintent.com', segment: [{ id: 'asa_1231' }, { id: 'lalo_4311' }, { id: 'liurl_99123' }] }] } } expect(ortb2).to.deep.equal(expectedOrtb2); }); }); diff --git a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js index f84d4ace1ff..2db52ba4cac 100644 --- a/test/spec/modules/livewrappedAnalyticsAdapter_spec.js +++ b/test/spec/modules/livewrappedAnalyticsAdapter_spec.js @@ -554,7 +554,7 @@ describe('Livewrapped analytics adapter', function () { 'bidId': '3ecff0db240757', 'lwflr': { 'flr': 1.1, - 'bflrs': {'livewrapped': 2.2} + 'bflrs': { 'livewrapped': 2.2 } } } ], diff --git a/test/spec/modules/livewrappedBidAdapter_spec.js b/test/spec/modules/livewrappedBidAdapter_spec.js index 86bb680436f..30dd1c4baf3 100644 --- a/test/spec/modules/livewrappedBidAdapter_spec.js +++ b/test/spec/modules/livewrappedBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec, storage} from 'modules/livewrappedBidAdapter.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec, storage } from 'modules/livewrappedBidAdapter.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import { NATIVE, VIDEO } from 'src/mediaTypes.js'; import { setConfig as setCurrencyConfig } from '../../../modules/currency.js'; @@ -32,7 +32,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']} + seats: { 'dsp': ['seat 1'] } }, adUnitCode: 'panorama_d_1', sizes: [[980, 240], [980, 120]], @@ -59,7 +59,7 @@ describe('Livewrapped adapter tests', function () { describe('isBidRequestValid', function() { it('should accept a request with id only as valid', function() { - const bid = {params: {adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37'}}; + const bid = { params: { adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37' } }; const result = spec.isBidRequestValid(bid); @@ -67,7 +67,7 @@ describe('Livewrapped adapter tests', function () { }); it('should accept a request with adUnitName and PublisherId as valid', function() { - const bid = {params: {adUnitName: 'panorama_d_1', publisherId: '26947112-2289-405D-88C1-A7340C57E63E'}}; + const bid = { params: { adUnitName: 'panorama_d_1', publisherId: '26947112-2289-405D-88C1-A7340C57E63E' } }; const result = spec.isBidRequestValid(bid); @@ -75,7 +75,7 @@ describe('Livewrapped adapter tests', function () { }); it('should accept a request with adUnitCode and PublisherId as valid', function() { - const bid = {adUnitCode: 'panorama_d_1', params: {publisherId: '26947112-2289-405D-88C1-A7340C57E63E'}}; + const bid = { adUnitCode: 'panorama_d_1', params: { publisherId: '26947112-2289-405D-88C1-A7340C57E63E' } }; const result = spec.isBidRequestValid(bid); @@ -83,7 +83,7 @@ describe('Livewrapped adapter tests', function () { }); it('should accept a request with placementCode and PublisherId as valid', function() { - const bid = {placementCode: 'panorama_d_1', params: {publisherId: '26947112-2289-405D-88C1-A7340C57E63E'}}; + const bid = { placementCode: 'panorama_d_1', params: { publisherId: '26947112-2289-405D-88C1-A7340C57E63E' } }; const result = spec.isBidRequestValid(bid); @@ -91,7 +91,7 @@ describe('Livewrapped adapter tests', function () { }); it('should not accept a request with adUnitName, adUnitCode, placementCode but no PublisherId as valid', function() { - const bid = {placementCode: 'panorama_d_1', adUnitCode: 'panorama_d_1', params: {adUnitName: 'panorama_d_1'}}; + const bid = { placementCode: 'panorama_d_1', adUnitCode: 'panorama_d_1', params: { adUnitName: 'panorama_d_1' } }; const result = spec.isBidRequestValid(bid); @@ -113,7 +113,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -122,7 +122,7 @@ describe('Livewrapped adapter tests', function () { adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', callerAdUnitId: 'panorama_d_1', bidId: '2ffb201a808da7', - formats: [{width: 980, height: 240}, {width: 980, height: 120}], + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], rtbData: { ext: { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' @@ -138,7 +138,7 @@ describe('Livewrapped adapter tests', function () { sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); const ortb2ImpRequest = clone(bidderRequest); - ortb2ImpRequest.bids[0].ortb2Imp.ext.data = {key: 'value'}; + ortb2ImpRequest.bids[0].ortb2Imp.ext.data = { key: 'value' }; const result = spec.buildRequests(ortb2ImpRequest.bids, ortb2ImpRequest); const data = JSON.parse(result.data); @@ -149,7 +149,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -158,10 +158,10 @@ describe('Livewrapped adapter tests', function () { adUnitId: '9E153CED-61BC-479E-98DF-24DC0D01BA37', callerAdUnitId: 'panorama_d_1', bidId: '2ffb201a808da7', - formats: [{width: 980, height: 240}, {width: 980, height: 120}], + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], rtbData: { ext: { - data: {key: 'value'}, + data: { key: 'value' }, tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, } @@ -191,7 +191,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -205,7 +205,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }, { callerAdUnitId: 'box_d_1', bidId: '3ffb201a808da7', @@ -214,7 +214,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 300, height: 250}] + formats: [{ width: 300, height: 250 }] }] }; @@ -237,7 +237,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -250,7 +250,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -285,7 +285,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -320,7 +320,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -357,7 +357,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -394,7 +394,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -408,7 +408,7 @@ describe('Livewrapped adapter tests', function () { delete testbidRequest.bids[0].params.userId; delete testbidRequest.bids[0].params.seats; delete testbidRequest.bids[0].params.adUnitId; - testbidRequest.bids[0].params.options = {keyvalues: [{key: 'key', value: 'value'}]}; + testbidRequest.bids[0].params.options = { keyvalues: [{ key: 'key', value: 'value' }] }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -428,8 +428,8 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}], - options: {keyvalues: [{key: 'key', value: 'value'}]} + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], + options: { keyvalues: [{ key: 'key', value: 'value' }] } }] }; @@ -464,7 +464,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -478,7 +478,7 @@ describe('Livewrapped adapter tests', function () { delete testbidRequest.bids[0].params.userId; delete testbidRequest.bids[0].params.seats; delete testbidRequest.bids[0].params.adUnitId; - testbidRequest.bids[0].mediaTypes = {'native': {'nativedata': 'content parsed serverside only'}}; + testbidRequest.bids[0].mediaTypes = { 'native': { 'nativedata': 'content parsed serverside only' } }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -498,8 +498,8 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}], - native: {'nativedata': 'content parsed serverside only'} + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], + native: { 'nativedata': 'content parsed serverside only' } }] }; @@ -513,7 +513,7 @@ describe('Livewrapped adapter tests', function () { delete testbidRequest.bids[0].params.userId; delete testbidRequest.bids[0].params.seats; delete testbidRequest.bids[0].params.adUnitId; - testbidRequest.bids[0].mediaTypes = {'native': {'nativedata': 'content parsed serverside only'}, 'banner': {'sizes': [[980, 240], [980, 120]]}}; + testbidRequest.bids[0].mediaTypes = { 'native': { 'nativedata': 'content parsed serverside only' }, 'banner': { 'sizes': [[980, 240], [980, 120]] } }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -533,8 +533,8 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}], - native: {'nativedata': 'content parsed serverside only'}, + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], + native: { 'nativedata': 'content parsed serverside only' }, banner: true }] }; @@ -549,7 +549,7 @@ describe('Livewrapped adapter tests', function () { delete testbidRequest.bids[0].params.userId; delete testbidRequest.bids[0].params.seats; delete testbidRequest.bids[0].params.adUnitId; - testbidRequest.bids[0].mediaTypes = {'video': {'videodata': 'content parsed serverside only'}}; + testbidRequest.bids[0].mediaTypes = { 'video': { 'videodata': 'content parsed serverside only' } }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -569,8 +569,8 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}], - video: {'videodata': 'content parsed serverside only'} + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], + video: { 'videodata': 'content parsed serverside only' } }] }; @@ -587,10 +587,10 @@ describe('Livewrapped adapter tests', function () { const origGetConfig = config.getConfig; sandbox.stub(config, 'getConfig').callsFake(function (key) { if (key === 'app') { - return {bundle: 'bundle', domain: 'https://appdomain.com'}; + return { bundle: 'bundle', domain: 'https://appdomain.com' }; } if (key === 'device') { - return {ifa: 'ifa', w: 300, h: 200}; + return { ifa: 'ifa', w: 300, h: 200 }; } return origGetConfig.apply(config, arguments); }); @@ -605,7 +605,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://appdomain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 300, height: 200, @@ -621,7 +621,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -635,7 +635,7 @@ describe('Livewrapped adapter tests', function () { delete testbidRequest.bids[0].params.userId; delete testbidRequest.bids[0].params.seats; delete testbidRequest.bids[0].params.adUnitId; - testbidRequest.bids[0].mediaTypes = {'banner': {'sizes': [[728, 90]]}}; + testbidRequest.bids[0].mediaTypes = { 'banner': { 'sizes': [[728, 90]] } }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -655,7 +655,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 728, height: 90}] + formats: [{ width: 728, height: 90 }] }] }; @@ -680,7 +680,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -696,7 +696,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -720,7 +720,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -735,7 +735,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -757,7 +757,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -772,7 +772,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -801,7 +801,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -816,7 +816,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -836,7 +836,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -850,7 +850,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -870,7 +870,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -884,7 +884,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -893,7 +893,7 @@ describe('Livewrapped adapter tests', function () { it('should use params.url, then bidderRequest.refererInfo.page', function() { const testRequest = clone(bidderRequest); - testRequest.refererInfo = {page: 'https://www.topurl.com'}; + testRequest.refererInfo = { page: 'https://www.topurl.com' }; let result = spec.buildRequests(testRequest.bids, testRequest); let data = JSON.parse(result.data); @@ -913,7 +913,7 @@ describe('Livewrapped adapter tests', function () { sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); const testbidRequest = clone(bidderRequest); delete testbidRequest.bids[0].params.userId; - testbidRequest.bids[0].crumbs = {pubcid: 'pubcid 123'}; + testbidRequest.bids[0].crumbs = { pubcid: 'pubcid 123' }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -924,7 +924,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'pubcid 123', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -938,7 +938,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -949,7 +949,7 @@ describe('Livewrapped adapter tests', function () { sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); const testbidRequest = clone(bidderRequest); - testbidRequest.bids[0].crumbs = {pubcid: 'pubcid 123'}; + testbidRequest.bids[0].crumbs = { pubcid: 'pubcid 123' }; const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); @@ -960,7 +960,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -974,7 +974,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -998,7 +998,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: getWinDimensions().innerWidth, height: getWinDimensions().innerHeight, @@ -1012,7 +1012,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -1036,7 +1036,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -1050,7 +1050,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -1076,7 +1076,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -1090,7 +1090,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -1116,7 +1116,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -1130,7 +1130,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -1156,7 +1156,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -1170,7 +1170,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}] + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }] }] }; @@ -1217,7 +1217,7 @@ describe('Livewrapped adapter tests', function () { publisherId: '26947112-2289-405D-88C1-A7340C57E63E', userId: 'user id', url: 'https://www.domain.com', - seats: {'dsp': ['seat 1']}, + seats: { 'dsp': ['seat 1'] }, version: '1.4', width: 100, height: 100, @@ -1232,7 +1232,7 @@ describe('Livewrapped adapter tests', function () { tid: '3D1C8CF7-D288-4D7F-8ADD-97C553056C3D' }, }, - formats: [{width: 980, height: 240}, {width: 980, height: 120}], + formats: [{ width: 980, height: 240 }, { width: 980, height: 120 }], flr: 10 }] }; @@ -1276,9 +1276,9 @@ describe('Livewrapped adapter tests', function () { sandbox.stub(utils, 'isSafariBrowser').callsFake(() => false); sandbox.stub(storage, 'cookiesAreEnabled').callsFake(() => true); - const ortb2 = {user: {ext: {prop: 'value'}}}; + const ortb2 = { user: { ext: { prop: 'value' } } }; - const testbidRequest = {...clone(bidderRequest), ortb2}; + const testbidRequest = { ...clone(bidderRequest), ortb2 }; delete testbidRequest.bids[0].params.userId; testbidRequest.bids[0].userIdAsEids = [ { @@ -1292,10 +1292,10 @@ describe('Livewrapped adapter tests', function () { const result = spec.buildRequests(testbidRequest.bids, testbidRequest); const data = JSON.parse(result.data); - var expected = {user: {ext: {prop: 'value', eids: testbidRequest.bids[0].userIdAsEids}}} + var expected = { user: { ext: { prop: 'value', eids: testbidRequest.bids[0].userIdAsEids } } } expect(data.rtbData).to.deep.equal(expected); - expect(ortb2).to.deep.equal({user: {ext: {prop: 'value'}}}); + expect(ortb2).to.deep.equal({ user: { ext: { prop: 'value' } } }); }); it('should send schain object if available', function() { @@ -1360,7 +1360,7 @@ describe('Livewrapped adapter tests', function () { meta: undefined }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1399,7 +1399,7 @@ describe('Livewrapped adapter tests', function () { meta: { dealId: "deal id", bidder: "bidder" } }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1439,7 +1439,7 @@ describe('Livewrapped adapter tests', function () { bidderCode: "bidder" }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1457,7 +1457,7 @@ describe('Livewrapped adapter tests', function () { bidId: '32e50fad901ae89', auctionId: '13e674db-d4d8-4e19-9d28-ff38177db8bf', creativeId: '52cbd598-2715-4c43-a06f-229fc170f945:427077', - native: {'native': 'native'}, + native: { 'native': 'native' }, ttl: 120, meta: undefined } @@ -1476,11 +1476,11 @@ describe('Livewrapped adapter tests', function () { netRevenue: true, currency: 'USD', meta: undefined, - native: {'native': 'native'}, + native: { 'native': 'native' }, mediaType: NATIVE }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1521,7 +1521,7 @@ describe('Livewrapped adapter tests', function () { mediaType: VIDEO }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1583,7 +1583,7 @@ describe('Livewrapped adapter tests', function () { meta: undefined }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1602,7 +1602,7 @@ describe('Livewrapped adapter tests', function () { auctionId: '13e674db-d4d8-4e19-9d28-ff38177db8bf', creativeId: '52cbd598-2715-4c43-a06f-229fc170f945:427077', ttl: 120, - meta: {metadata: 'metadata'} + meta: { metadata: 'metadata' } } ], currency: 'USD' @@ -1618,10 +1618,10 @@ describe('Livewrapped adapter tests', function () { creativeId: '52cbd598-2715-4c43-a06f-229fc170f945:427077', netRevenue: true, currency: 'USD', - meta: {metadata: 'metadata'} + meta: { metadata: 'metadata' } }]; - const bids = spec.interpretResponse({body: lwResponse}); + const bids = spec.interpretResponse({ body: lwResponse }); expect(bids).to.deep.equal(expectedResponse); }) @@ -1654,7 +1654,7 @@ describe('Livewrapped adapter tests', function () { } }; - spec.interpretResponse({body: lwResponse}); + spec.interpretResponse({ body: lwResponse }); expect(debugData).to.equal(lwResponse.dbg); }) @@ -1667,8 +1667,8 @@ describe('Livewrapped adapter tests', function () { serverResponses = [{ body: { pixels: [ - {type: 'Redirect', url: 'https://pixelsync'}, - {type: 'Iframe', url: 'https://iframesync'} + { type: 'Redirect', url: 'https://pixelsync' }, + { type: 'Iframe', url: 'https://iframesync' } ] } }]; @@ -1689,7 +1689,7 @@ describe('Livewrapped adapter tests', function () { const syncs = spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true - }, [{body: {}}]); + }, [{ body: {} }]); const expectedResponse = []; @@ -1702,7 +1702,7 @@ describe('Livewrapped adapter tests', function () { iframeEnabled: true }, serverResponses); - const expectedResponse = [{type: 'image', url: 'https://pixelsync'}, {type: 'iframe', url: 'https://iframesync'}]; + const expectedResponse = [{ type: 'image', url: 'https://pixelsync' }, { type: 'iframe', url: 'https://iframesync' }]; expect(syncs).to.deep.equal(expectedResponse) }); @@ -1713,7 +1713,7 @@ describe('Livewrapped adapter tests', function () { iframeEnabled: false }, serverResponses); - const expectedResponse = [{type: 'image', url: 'https://pixelsync'}]; + const expectedResponse = [{ type: 'image', url: 'https://pixelsync' }]; expect(syncs).to.deep.equal(expectedResponse) }); @@ -1724,7 +1724,7 @@ describe('Livewrapped adapter tests', function () { iframeEnabled: true }, serverResponses); - const expectedResponse = [{type: 'iframe', url: 'https://iframesync'}]; + const expectedResponse = [{ type: 'iframe', url: 'https://iframesync' }]; expect(syncs).to.deep.equal(expectedResponse) }); diff --git a/test/spec/modules/lm_kiviadsBidAdapter_spec.js b/test/spec/modules/lm_kiviadsBidAdapter_spec.js index 32b8d56309b..0ed1fb9793d 100644 --- a/test/spec/modules/lm_kiviadsBidAdapter_spec.js +++ b/test/spec/modules/lm_kiviadsBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/lm_kiviadsBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/lm_kiviadsBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; const ENDPOINT = 'https://pbjs.kiviads.live'; @@ -99,7 +99,7 @@ describe('lm_kiviadsBidAdapter', () => { expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); expect(request).to.have.property('floor').and.to.equal(null); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -192,7 +192,7 @@ describe('lm_kiviadsBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -208,8 +208,8 @@ describe('lm_kiviadsBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -261,7 +261,7 @@ describe('lm_kiviadsBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -270,7 +270,7 @@ describe('lm_kiviadsBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['lm_kiviads']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['lm_kiviads'] }); }); it('should interpret valid banner response', function () { @@ -291,7 +291,7 @@ describe('lm_kiviadsBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -317,7 +317,7 @@ describe('lm_kiviadsBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: defaultRequestVideo}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: defaultRequestVideo }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -333,12 +333,12 @@ describe('lm_kiviadsBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -357,7 +357,7 @@ describe('lm_kiviadsBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -376,7 +376,7 @@ describe('lm_kiviadsBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -400,20 +400,20 @@ describe('lm_kiviadsBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -421,7 +421,7 @@ describe('lm_kiviadsBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -429,7 +429,7 @@ describe('lm_kiviadsBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/lmpIdSystem_spec.js b/test/spec/modules/lmpIdSystem_spec.js index cf525121fad..d7f3591c6be 100644 --- a/test/spec/modules/lmpIdSystem_spec.js +++ b/test/spec/modules/lmpIdSystem_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {lmpIdSubmodule, storage} from 'modules/lmpIdSystem.js'; +import { expect } from 'chai'; +import { lmpIdSubmodule, storage } from 'modules/lmpIdSystem.js'; describe('LMPID System', () => { let getDataFromLocalStorageStub, localStorageIsEnabledStub; diff --git a/test/spec/modules/locIdSystem_spec.js b/test/spec/modules/locIdSystem_spec.js new file mode 100644 index 00000000000..1b2fc02ddc8 --- /dev/null +++ b/test/spec/modules/locIdSystem_spec.js @@ -0,0 +1,2090 @@ +/** + * This file is licensed under the Apache 2.0 license. + * http://www.apache.org/licenses/LICENSE-2.0 + */ + +import { locIdSubmodule, storage } from 'modules/locIdSystem.js'; +import { createEidsArray } from 'modules/userId/eids.js'; +import { attachIdSystem } from 'modules/userId/index.js'; +import * as ajax from 'src/ajax.js'; +import { VENDORLESS_GVLID } from 'src/consentHandler.js'; +import { uspDataHandler, gppDataHandler } from 'src/adapterManager.js'; +import { expect } from 'chai/index.mjs'; +import sinon from 'sinon'; + +const TEST_ID = 'SYybozbTuRaZkgGqCD7L7EE0FncoNUcx-om4xTfhJt36TFIAES2tF1qPH'; +const TEST_ENDPOINT = 'https://id.example.com/locid'; +const TEST_CONNECTION_IP = '203.0.113.42'; + +describe('LocID System', () => { + let sandbox; + let ajaxStub; + let ajaxBuilderStub; + + beforeEach(() => { + sandbox = sinon.createSandbox(); + sandbox.stub(uspDataHandler, 'getConsentData').returns(null); + sandbox.stub(gppDataHandler, 'getConsentData').returns(null); + sandbox.stub(storage, 'getDataFromLocalStorage').returns(null); + sandbox.stub(storage, 'setDataInLocalStorage'); + ajaxStub = sandbox.stub(); + ajaxBuilderStub = sandbox.stub(ajax, 'ajaxBuilder').returns(ajaxStub); + }); + + afterEach(() => { + sandbox.restore(); + }); + + describe('module properties', () => { + it('should expose correct module name', () => { + expect(locIdSubmodule.name).to.equal('locId'); + }); + + it('should have eids configuration with correct defaults', () => { + expect(locIdSubmodule.eids).to.be.an('object'); + expect(locIdSubmodule.eids.locId).to.be.an('object'); + expect(locIdSubmodule.eids.locId.source).to.equal('locid.com'); + // atype 1 = AdCOM AgentTypeWeb + expect(locIdSubmodule.eids.locId.atype).to.equal(1); + }); + + it('should register as a vendorless TCF module', () => { + expect(locIdSubmodule.gvlid).to.equal(VENDORLESS_GVLID); + }); + + it('should have getValue function that extracts ID', () => { + const getValue = locIdSubmodule.eids.locId.getValue; + expect(getValue('test-id')).to.equal('test-id'); + expect(getValue({ id: 'id-shape' })).to.equal('id-shape'); + expect(getValue({ locId: 'test-id' })).to.equal('test-id'); + expect(getValue({ locid: 'legacy-id' })).to.equal('legacy-id'); + }); + }); + + describe('decode', () => { + it('should decode valid ID correctly', () => { + const result = locIdSubmodule.decode({ id: TEST_ID, connectionIp: TEST_CONNECTION_IP }); + expect(result).to.deep.equal({ locId: TEST_ID }); + }); + + it('should decode ID passed as object', () => { + const result = locIdSubmodule.decode({ id: TEST_ID, connectionIp: TEST_CONNECTION_IP }); + expect(result).to.deep.equal({ locId: TEST_ID }); + }); + + it('should return undefined for invalid values', () => { + [null, undefined, '', {}, [], 123, TEST_ID].forEach(value => { + expect(locIdSubmodule.decode(value)).to.be.undefined; + }); + }); + + it('should return undefined when connection_ip is missing', () => { + expect(locIdSubmodule.decode({ id: TEST_ID })).to.be.undefined; + }); + + it('should return undefined for IDs exceeding max length', () => { + const longId = 'a'.repeat(513); + expect(locIdSubmodule.decode({ id: longId, connectionIp: TEST_CONNECTION_IP })).to.be.undefined; + }); + + it('should accept ID at exactly MAX_ID_LENGTH (512 characters)', () => { + const maxLengthId = 'a'.repeat(512); + const result = locIdSubmodule.decode({ id: maxLengthId, connectionIp: TEST_CONNECTION_IP }); + expect(result).to.deep.equal({ locId: maxLengthId }); + }); + }); + + describe('getId', () => { + it('should return callback for async endpoint fetch', () => { + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + const result = locIdSubmodule.getId(config, {}); + expect(result).to.have.property('callback'); + expect(result.callback).to.be.a('function'); + }); + + it('should call endpoint and return tx_cloc on success', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.equal(TEST_ID); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + expect(ajaxStub.calledOnce).to.be.true; + done(); + }); + }); + + it('should cache entry with null id when tx_cloc is missing but connection_ip is present', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ stable_cloc: 'stable-cloc-id-12345', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.be.null; + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should prefer tx_cloc over stable_cloc when both present', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ + tx_cloc: TEST_ID, + stable_cloc: 'stable-fallback', + connection_ip: TEST_CONNECTION_IP + })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.equal(TEST_ID); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should return undefined on endpoint error', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.error('Network error'); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.undefined; + done(); + }); + }); + + it('should reuse storedId when valid and IP cache matches', () => { + // Set up IP cache matching stored entry's IP + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const config = { + params: { + endpoint: TEST_ENDPOINT + }, + storage: { + name: '_locid' + } + }; + const storedId = { + id: 'existing-id', + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + updatedAt: Date.now(), + expiresAt: Date.now() + 1000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + expect(ajaxStub.called).to.be.false; + }); + + it('should not reuse storedId when expired', () => { + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + const storedId = { + id: 'expired-id', + connectionIp: TEST_CONNECTION_IP, + createdAt: 1000, + updatedAt: 1000, + expiresAt: Date.now() - 1000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result).to.have.property('callback'); + }); + + it('should not reuse storedId when connectionIp is missing', () => { + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + const storedId = { + id: 'existing-id', + createdAt: 1000, + updatedAt: 1000, + expiresAt: 2000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result).to.have.property('callback'); + }); + + it('should pass x-api-key header when apiKey is configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(options.customHeaders).to.deep.equal({ 'x-api-key': 'test-api-key' }); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + apiKey: 'test-api-key' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should not include customHeaders when apiKey is not configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(options.customHeaders).to.not.exist; + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should pass withCredentials when configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(options.withCredentials).to.be.true; + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + withCredentials: true + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should default withCredentials to false', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(options.withCredentials).to.be.false; + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should use default timeout of 800ms when timeoutMs is not configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + expect(ajaxBuilderStub.calledWith(800)).to.be.true; + done(); + }); + }); + + it('should use custom timeout when timeoutMs is configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + timeoutMs: 1500 + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + expect(ajaxBuilderStub.calledWith(1500)).to.be.true; + done(); + }); + }); + + it('should always use GET method', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(options.method).to.equal('GET'); + expect(body).to.be.null; + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should append alt_id query parameter when altId is configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal(TEST_ENDPOINT + '?alt_id=user123'); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + altId: 'user123' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should use & separator when endpoint already has query params', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal(TEST_ENDPOINT + '?existing=param&alt_id=user456'); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + '?existing=param', + altId: 'user456' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should URL-encode altId value', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal(TEST_ENDPOINT + '?alt_id=user%40example.com'); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + altId: 'user@example.com' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should not append alt_id when altId is not configured', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal(TEST_ENDPOINT); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should preserve URL fragment when appending alt_id', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal('https://id.example.com/locid?alt_id=user123#frag'); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: 'https://id.example.com/locid#frag', + altId: 'user123' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should preserve URL fragment when endpoint has existing query params', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + expect(url).to.equal('https://id.example.com/locid?x=1&alt_id=user456#frag'); + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: 'https://id.example.com/locid?x=1#frag', + altId: 'user456' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => done()); + }); + + it('should return undefined via callback when endpoint is empty string', (done) => { + const config = { + params: { + endpoint: '' + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.undefined; + expect(ajaxStub.called).to.be.false; + done(); + }); + }); + }); + + describe('extendId', () => { + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + it('should return stored id when valid and IP cache is current', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 14400000 + })); + const storedId = { id: 'existing-id', connectionIp: TEST_CONNECTION_IP }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + }); + + it('should reuse storedId when refreshInSeconds is configured but not due', () => { + const now = Date.now(); + const refreshInSeconds = 60; + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: now, + expiresAt: now + 14400000 + })); + const storedId = { + id: 'existing-id', + connectionIp: TEST_CONNECTION_IP, + createdAt: now - ((refreshInSeconds - 10) * 1000), + expiresAt: now + 10000 + }; + const refreshConfig = { + params: { + endpoint: TEST_ENDPOINT + }, + storage: { + refreshInSeconds + } + }; + const result = locIdSubmodule.extendId(refreshConfig, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + }); + + it('should return undefined when refreshInSeconds is due', () => { + const now = Date.now(); + const refreshInSeconds = 60; + const storedId = { + id: 'existing-id', + connectionIp: TEST_CONNECTION_IP, + createdAt: now - ((refreshInSeconds + 10) * 1000), + expiresAt: now + 10000 + }; + const refreshConfig = { + params: { + endpoint: TEST_ENDPOINT + }, + storage: { + refreshInSeconds + } + }; + const result = locIdSubmodule.extendId(refreshConfig, {}, storedId); + expect(result).to.be.undefined; + }); + + it('should return undefined when refreshInSeconds is configured and createdAt is missing', () => { + const now = Date.now(); + const refreshInSeconds = 60; + const storedId = { + id: 'existing-id', + connectionIp: TEST_CONNECTION_IP, + expiresAt: now + 10000 + }; + const refreshConfig = { + params: { + endpoint: TEST_ENDPOINT + }, + storage: { + refreshInSeconds + } + }; + const result = locIdSubmodule.extendId(refreshConfig, {}, storedId); + expect(result).to.be.undefined; + }); + + it('should return undefined when storedId is a string', () => { + const result = locIdSubmodule.extendId(config, {}, 'existing-id'); + expect(result).to.be.undefined; + }); + + it('should return undefined when connectionIp is missing', () => { + const result = locIdSubmodule.extendId(config, {}, { id: 'existing-id' }); + expect(result).to.be.undefined; + }); + + it('should return undefined when stored entry is expired', () => { + const storedId = { + id: 'existing-id', + connectionIp: TEST_CONNECTION_IP, + expiresAt: Date.now() - 1000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.be.undefined; + }); + }); + + describe('privacy framework handling', () => { + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + // --- Tests for no privacy signals (LI-based operation) --- + // LocID operates under Legitimate Interest and should proceed when no + // privacy framework is present, unless requirePrivacySignals is enabled. + + it('should proceed when no consentData provided at all (default LI-based operation)', () => { + // When no privacy signals are present, module should proceed by default + const result = locIdSubmodule.getId(config, undefined); + expect(result).to.have.property('callback'); + }); + + it('should proceed when consentData is null (default LI-based operation)', () => { + const result = locIdSubmodule.getId(config, null); + expect(result).to.have.property('callback'); + }); + + it('should proceed when consentData is empty object (default LI-based operation)', () => { + // Empty object has no privacy signals, so should proceed + const result = locIdSubmodule.getId(config, {}); + expect(result).to.have.property('callback'); + }); + + it('should return undefined when no consentData and requirePrivacySignals=true', () => { + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + requirePrivacySignals: true + } + }; + const result = locIdSubmodule.getId(strictConfig, undefined); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined when empty consentData and requirePrivacySignals=true', () => { + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + requirePrivacySignals: true + } + }; + const result = locIdSubmodule.getId(strictConfig, {}); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined when no consentData and privacyMode=requireSignals', () => { + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + privacyMode: 'requireSignals' + } + }; + const result = locIdSubmodule.getId(strictConfig, undefined); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should proceed when no consentData and privacyMode=allowWithoutSignals', () => { + const permissiveConfig = { + params: { + endpoint: TEST_ENDPOINT, + privacyMode: 'allowWithoutSignals' + } + }; + const result = locIdSubmodule.getId(permissiveConfig, undefined); + expect(result).to.have.property('callback'); + }); + + it('should proceed with privacy signals present and requirePrivacySignals=true', () => { + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + requirePrivacySignals: true + } + }; + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: {} + } + }; + const result = locIdSubmodule.getId(strictConfig, consentData); + expect(result).to.have.property('callback'); + }); + + it('should detect privacy signals from uspDataHandler and block on processing restriction', () => { + // Restore and re-stub to return USP processing restriction signal + uspDataHandler.getConsentData.restore(); + sandbox.stub(uspDataHandler, 'getConsentData').returns('1YY-'); + + // Even with empty consentData, handler provides privacy signal + const result = locIdSubmodule.getId(config, {}); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should detect privacy signals from gppDataHandler and block on processing restriction', () => { + // Restore and re-stub to return GPP processing restriction signal + gppDataHandler.getConsentData.restore(); + sandbox.stub(gppDataHandler, 'getConsentData').returns({ + applicableSections: [7], + parsedSections: { + usnat: { + KnownChildSensitiveDataConsents: [1] + } + } + }); + + // Even with empty consentData, handler provides privacy signal + const result = locIdSubmodule.getId(config, {}); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should proceed when uspDataHandler returns non-restrictive value', () => { + // Restore and re-stub to return non-restrictive USP + uspDataHandler.getConsentData.restore(); + sandbox.stub(uspDataHandler, 'getConsentData').returns('1NN-'); + + const result = locIdSubmodule.getId(config, {}); + expect(result).to.have.property('callback'); + }); + + // --- Tests for gdprApplies edge cases (LI-based operation) --- + // gdprApplies alone does NOT constitute a privacy signal. + // A GDPR signal requires actual CMP artifacts (consentString or vendorData). + + it('should proceed when gdprApplies=true but no consentString/vendorData (default LI mode)', () => { + // gdprApplies alone is not a signal - allows LI-based operation without CMP + const consentData = { + gdprApplies: true + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when gdprApplies=true and usp is present but no GDPR CMP artifacts', () => { + const consentData = { + gdprApplies: true, + usp: '1NN-' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when gdprApplies=true and consentString is empty (treated as absent CMP artifact)', () => { + // Empty consentString is treated as not present, so LI-mode behavior applies. + const consentData = { + gdprApplies: true, + consentString: '' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should return undefined when gdprApplies=true, no CMP artifacts, and strict mode', () => { + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + requirePrivacySignals: true + } + }; + const consentData = { + gdprApplies: true + }; + const result = locIdSubmodule.getId(strictConfig, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined when gdprApplies=true, vendorData present but no consentString', () => { + // vendorData presence = CMP is present, so signals ARE present + // GDPR applies + signals present + no consentString → deny + const consentData = { + gdprApplies: true, + vendorData: { + vendor: {} + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should deny when gdprApplies=false and strict mode is enabled (gdprApplies alone is not a signal)', () => { + // gdprApplies=false alone is not a signal, so strict mode blocks + const strictConfig = { + params: { + endpoint: TEST_ENDPOINT, + requirePrivacySignals: true + } + }; + const consentData = { + gdprApplies: false + }; + const result = locIdSubmodule.getId(strictConfig, consentData); + // gdprApplies=false is not a signal, so strict mode denies + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + // --- Original tests for when privacy signals ARE present --- + + it('should proceed with valid GDPR framework data', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR does not apply (no CMP artifacts)', () => { + // gdprApplies=false alone is not a signal - LI operation allowed + const consentData = { + gdprApplies: false + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR applies with consentString and vendor flags deny', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: false }, + legitimateInterests: { 999: false } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should return undefined on US Privacy processing restriction and not call ajax', () => { + const consentData = { + usp: '1YY-' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined on legacy US Privacy processing restriction and not call ajax', () => { + const consentData = { + uspConsent: '1YY-' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined on GPP processing restriction and not call ajax', () => { + const consentData = { + gpp: { + applicableSections: [7], + parsedSections: { + usnat: { + KnownChildSensitiveDataConsents: [1] + } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should return undefined on legacy GPP processing restriction and not call ajax', () => { + const consentData = { + gppConsent: { + applicableSections: [7], + parsedSections: { + usnat: { + KnownChildSensitiveDataConsents: [1] + } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.be.undefined; + expect(ajaxStub.called).to.be.false; + }); + + it('should proceed when nested GDPR applies but no CMP artifacts (LI operation)', () => { + // Empty consentString in nested gdpr object is not a signal - LI operation allowed + const consentData = { + gdpr: { + gdprApplies: true, + consentString: '' + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed with valid nested GDPR framework data', () => { + const consentData = { + gdpr: { + gdprApplies: true, + consentString: 'valid-consent-string' + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR applies and vendorData is present', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: false }, + legitimateInterests: { 999: false } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR applies and vendor is missing from consents', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 1234: true }, + legitimateInterests: { 1234: true } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR applies and vendor consents object is present', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: true } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when GDPR applies and vendor legitimate interests object is present', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: false }, + legitimateInterests: { 999: true } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when vendorData is not available (cannot determine vendor permission)', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string' + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should check nested vendorData when using gdpr object shape', () => { + const consentData = { + gdpr: { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: true } + } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when nested vendorData has explicit deny flags', () => { + const consentData = { + gdpr: { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: { 999: false }, + legitimateInterests: {} + } + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when vendor consents is a function returning true', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: (id) => id === 999, + legitimateInterests: {} + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when vendor legitimateInterests is a function returning true', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: (id) => false, + legitimateInterests: (id) => id === 999 + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + + it('should proceed when vendor consent callbacks both return false', () => { + const consentData = { + gdprApplies: true, + consentString: 'valid-consent-string', + vendorData: { + vendor: { + consents: (id) => false, + legitimateInterests: (id) => false + } + } + }; + const result = locIdSubmodule.getId(config, consentData); + expect(result).to.have.property('callback'); + }); + }); + + describe('response parsing', () => { + it('should parse JSON string response', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success('{"tx_cloc":"parsed-id","connection_ip":"203.0.113.42"}'); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.equal('parsed-id'); + expect(id.connectionIp).to.equal('203.0.113.42'); + done(); + }); + }); + + it('should return undefined when connection_ip is missing', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.undefined; + done(); + }); + }); + + it('should return undefined for invalid JSON', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success('not valid json'); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.undefined; + done(); + }); + }); + + it('should cache entry with null id when tx_cloc is empty string', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: '', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.be.null; + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should cache entry with null id when tx_cloc is whitespace-only', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ tx_cloc: ' \n\t ', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.be.null; + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should return undefined when tx_cloc is missing', (done) => { + ajaxStub.callsFake((url, callbacks, body, options) => { + callbacks.success(JSON.stringify({ other_field: 'value' })); + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT + } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.undefined; + done(); + }); + }); + }); + + describe('empty tx_cloc handling', () => { + it('should decode null id as undefined (no EID emitted)', () => { + const result = locIdSubmodule.decode({ id: null, connectionIp: TEST_CONNECTION_IP }); + expect(result).to.be.undefined; + }); + + it('should cache empty tx_cloc response for the full cache period', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { expires: 7 } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.be.null; + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + expect(id.expiresAt).to.be.a('number'); + expect(id.expiresAt).to.be.greaterThan(Date.now()); + done(); + }); + }); + + it('should reuse cached entry with null id on subsequent getId calls', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: null, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + updatedAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + expect(ajaxStub.called).to.be.false; + }); + + it('should not produce EID when tx_cloc is null', () => { + const decoded = locIdSubmodule.decode({ id: null, connectionIp: TEST_CONNECTION_IP }); + expect(decoded).to.be.undefined; + }); + + it('should write IP cache when endpoint returns empty tx_cloc', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + expect(storage.setDataInLocalStorage.called).to.be.true; + const callArgs = storage.setDataInLocalStorage.getCall(0).args; + expect(callArgs[0]).to.equal('_locid_ip'); + const ipEntry = JSON.parse(callArgs[1]); + expect(ipEntry.ip).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + }); + + describe('IP cache management', () => { + const ipCacheConfig = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + + it('should read valid IP cache entry', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + // If IP cache is valid and stored entry matches, should reuse + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.getId(ipCacheConfig, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + expect(ajaxStub.called).to.be.false; + }); + + it('should treat expired IP cache as missing', (done) => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now() - 20000, + expiresAt: Date.now() - 1000 + })); + + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.getId(ipCacheConfig, {}, storedId); + // Expired IP cache → calls main endpoint + expect(result).to.have.property('callback'); + result.callback((id) => { + expect(id).to.be.an('object'); + done(); + }); + }); + + it('should handle corrupted IP cache JSON gracefully', (done) => { + storage.getDataFromLocalStorage.returns('not-valid-json'); + + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const result = locIdSubmodule.getId(ipCacheConfig, {}); + expect(result).to.have.property('callback'); + result.callback((id) => { + expect(id).to.be.an('object'); + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + + it('should derive IP cache key from storage name', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: 'custom_key' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + const setCall = storage.setDataInLocalStorage.getCall(0); + expect(setCall.args[0]).to.equal('custom_key_ip'); + done(); + }); + }); + + it('should use custom ipCacheName when configured', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT, ipCacheName: 'my_ip_cache' }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + const setCall = storage.setDataInLocalStorage.getCall(0); + expect(setCall.args[0]).to.equal('my_ip_cache'); + done(); + }); + }); + + it('should use custom ipCacheTtlMs when configured', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT, ipCacheTtlMs: 7200000 }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback(() => { + const setCall = storage.setDataInLocalStorage.getCall(0); + const ipEntry = JSON.parse(setCall.args[1]); + // TTL should be ~2 hours + const ttl = ipEntry.expiresAt - ipEntry.fetchedAt; + expect(ttl).to.equal(7200000); + done(); + }); + }); + + it('should write IP cache on every successful main endpoint response', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: '10.0.0.1' })); + }); + + const result = locIdSubmodule.getId(ipCacheConfig, {}); + result.callback(() => { + expect(storage.setDataInLocalStorage.called).to.be.true; + const ipEntry = JSON.parse(storage.setDataInLocalStorage.getCall(0).args[1]); + expect(ipEntry.ip).to.equal('10.0.0.1'); + done(); + }); + }); + }); + + describe('getId with ipEndpoint (two-call optimization)', () => { + it('should call ipEndpoint first when IP cache is expired', (done) => { + let callCount = 0; + ajaxStub.callsFake((url, callbacks) => { + callCount++; + if (url === 'https://ip.example.com/check') { + callbacks.success(JSON.stringify({ ip: '10.0.0.1' })); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: '10.0.0.1' })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + // IP changed (no stored entry) → 2 calls: ipEndpoint + main endpoint + expect(callCount).to.equal(2); + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + + it('should reuse cached tx_cloc when ipEndpoint returns same IP', (done) => { + let callCount = 0; + ajaxStub.callsFake((url, callbacks) => { + callCount++; + if (url === 'https://ip.example.com/check') { + callbacks.success(JSON.stringify({ ip: TEST_CONNECTION_IP })); + } else { + callbacks.success(JSON.stringify({ tx_cloc: 'new-id', connection_ip: TEST_CONNECTION_IP })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // IP unchanged → only 1 call (ipEndpoint), reuses stored tx_cloc + expect(callCount).to.equal(1); + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + + it('should call main endpoint when ipEndpoint returns different IP', (done) => { + let callCount = 0; + ajaxStub.callsFake((url, callbacks) => { + callCount++; + if (url === 'https://ip.example.com/check') { + callbacks.success(JSON.stringify({ ip: '10.0.0.99' })); + } else { + callbacks.success(JSON.stringify({ tx_cloc: 'new-id', connection_ip: '10.0.0.99' })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // IP changed → 2 calls: ipEndpoint + main endpoint + expect(callCount).to.equal(2); + expect(id.id).to.equal('new-id'); + done(); + }); + }); + + it('should fall back to main endpoint when ipEndpoint fails', (done) => { + let callCount = 0; + ajaxStub.callsFake((url, callbacks) => { + callCount++; + if (url === 'https://ip.example.com/check') { + callbacks.error('Network error'); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(callCount).to.equal(2); + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + + it('should fall back to main endpoint when ipEndpoint returns invalid IP', (done) => { + let callCount = 0; + ajaxStub.callsFake((url, callbacks) => { + callCount++; + if (url === 'https://ip.example.com/check') { + callbacks.success('not-an-ip!!!'); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(callCount).to.equal(2); + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + + it('should pass apiKey header to ipEndpoint when configured', (done) => { + ajaxStub.callsFake((url, callbacks, _body, options) => { + if (url === 'https://ip.example.com/check') { + expect(options.customHeaders).to.deep.equal({ 'x-api-key': 'test-key-123' }); + callbacks.success(JSON.stringify({ ip: TEST_CONNECTION_IP })); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check', + apiKey: 'test-key-123' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + done(); + }); + }); + + it('should parse plain text IP from ipEndpoint', (done) => { + ajaxStub.callsFake((url, callbacks) => { + if (url === 'https://ip.example.com/check') { + callbacks.success(TEST_CONNECTION_IP); + } else { + callbacks.success(JSON.stringify({ tx_cloc: 'new-id', connection_ip: TEST_CONNECTION_IP })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // IP same → reuses stored tx_cloc + expect(id.id).to.equal(TEST_ID); + done(); + }); + }); + }); + + describe('getId tx_cloc preservation (no churn)', () => { + it('should preserve existing tx_cloc when main endpoint returns same IP', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // IP unchanged → preserve existing tx_cloc (don't churn) + expect(id.id).to.equal(TEST_ID); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should use fresh non-null tx_cloc when stored entry is null for same IP', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: null, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + expect(id.id).to.equal('fresh-id'); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should use fresh tx_cloc when main endpoint returns different IP', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: '10.0.0.99' })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // IP changed → use fresh tx_cloc + expect(id.id).to.equal('fresh-id'); + expect(id.connectionIp).to.equal('10.0.0.99'); + done(); + }); + }); + + it('should use fresh tx_cloc when stored entry is expired even if IP matches', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now() - 86400000, + expiresAt: Date.now() - 1000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // tx_cloc expired → use fresh even though IP matches + expect(id.id).to.equal('fresh-id'); + done(); + }); + }); + + it('should honor null tx_cloc from main endpoint even when stored entry is reusable', (done) => { + // Server returns connection_ip but no tx_cloc → freshEntry.id === null. + // The stored entry has a valid tx_cloc for the same IP, but the server + // now indicates no ID for this IP. The null response must be honored. + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + + const result = locIdSubmodule.getId(config, {}, storedId); + result.callback((id) => { + // Server said no tx_cloc → stored entry must NOT be preserved + expect(id.id).to.be.null; + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should use fresh entry on first load (no stored entry)', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: TEST_CONNECTION_IP })); + }); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id.id).to.equal(TEST_ID); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + }); + + describe('extendId with null id and IP cache', () => { + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + + it('should accept stored entry with null id (empty tx_cloc)', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 14400000 + })); + const storedId = { + id: null, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + }); + + it('should return refresh callback when IP cache shows different IP', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: '10.0.0.99' })); + }); + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: '10.0.0.99', + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.have.property('callback'); + result.callback((id) => { + expect(id.id).to.equal('fresh-id'); + expect(id.connectionIp).to.equal('10.0.0.99'); + done(); + }); + }); + + it('should extend when IP cache matches stored entry IP', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + }); + + it('should return refresh callback when IP cache is missing', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: TEST_CONNECTION_IP })); + }); + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.have.property('callback'); + result.callback((id) => { + expect(id.id).to.equal('fresh-id'); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should return refresh callback when IP cache is expired', (done) => { + ajaxStub.callsFake((url, callbacks) => { + callbacks.success(JSON.stringify({ tx_cloc: 'fresh-id', connection_ip: TEST_CONNECTION_IP })); + }); + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now() - 14400000, + expiresAt: Date.now() - 1000 + })); + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.have.property('callback'); + result.callback((id) => { + expect(id.id).to.equal('fresh-id'); + expect(id.connectionIp).to.equal(TEST_CONNECTION_IP); + done(); + }); + }); + + it('should return undefined for undefined id (not null, not valid string)', () => { + const storedId = { + id: undefined, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.extendId(config, {}, storedId); + expect(result).to.be.undefined; + }); + }); + + describe('normalizeStoredId with null id', () => { + it('should preserve explicit null id', () => { + // getId is the public interface; test via decode which uses normalized values + const stored = { id: null, connectionIp: TEST_CONNECTION_IP }; + // decode returns undefined for null id (correct: no EID emitted) + const decoded = locIdSubmodule.decode(stored); + expect(decoded).to.be.undefined; + }); + + it('should preserve valid string id', () => { + const stored = { id: TEST_ID, connectionIp: TEST_CONNECTION_IP }; + const decoded = locIdSubmodule.decode(stored); + expect(decoded).to.deep.equal({ locId: TEST_ID }); + }); + + it('should fall back to tx_cloc when id key is absent', () => { + const stored = { tx_cloc: TEST_ID, connectionIp: TEST_CONNECTION_IP }; + const decoded = locIdSubmodule.decode(stored); + expect(decoded).to.deep.equal({ locId: TEST_ID }); + }); + + it('should handle connection_ip alias', () => { + const stored = { id: TEST_ID, connection_ip: TEST_CONNECTION_IP }; + const decoded = locIdSubmodule.decode(stored); + expect(decoded).to.deep.equal({ locId: TEST_ID }); + }); + }); + + describe('parseIpResponse via ipEndpoint', () => { + it('should parse JSON with ip field', (done) => { + ajaxStub.callsFake((url, callbacks) => { + if (url === 'https://ip.example.com/check') { + callbacks.success('{"ip":"1.2.3.4"}'); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: '1.2.3.4' })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + // IP fetched and used + expect(id).to.be.an('object'); + done(); + }); + }); + + it('should parse JSON with connection_ip field', (done) => { + ajaxStub.callsFake((url, callbacks) => { + if (url === 'https://ip.example.com/check') { + callbacks.success('{"connection_ip":"1.2.3.4"}'); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: '1.2.3.4' })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + done(); + }); + }); + + it('should parse plain text IP address', (done) => { + ajaxStub.callsFake((url, callbacks) => { + if (url === 'https://ip.example.com/check') { + callbacks.success('1.2.3.4\n'); + } else { + callbacks.success(JSON.stringify({ tx_cloc: TEST_ID, connection_ip: '1.2.3.4' })); + } + }); + + const config = { + params: { + endpoint: TEST_ENDPOINT, + ipEndpoint: 'https://ip.example.com/check' + }, + storage: { name: '_locid' } + }; + + const result = locIdSubmodule.getId(config, {}); + result.callback((id) => { + expect(id).to.be.an('object'); + done(); + }); + }); + }); + + describe('backward compatibility', () => { + it('should work with existing stored entries that have string ids', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result).to.deep.equal({ id: storedId }); + }); + + it('should work with stored entries using connection_ip alias', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + id: TEST_ID, + connection_ip: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result.id.connectionIp).to.equal(TEST_CONNECTION_IP); + }); + + it('should work with stored entries using tx_cloc alias', () => { + storage.getDataFromLocalStorage.returns(JSON.stringify({ + ip: TEST_CONNECTION_IP, + fetchedAt: Date.now(), + expiresAt: Date.now() + 1000 + })); + + const config = { + params: { endpoint: TEST_ENDPOINT }, + storage: { name: '_locid' } + }; + const storedId = { + tx_cloc: TEST_ID, + connectionIp: TEST_CONNECTION_IP, + createdAt: Date.now(), + expiresAt: Date.now() + 86400000 + }; + const result = locIdSubmodule.getId(config, {}, storedId); + expect(result.id.id).to.equal(TEST_ID); + }); + }); + + describe('EID round-trip integration', () => { + before(() => { + attachIdSystem(locIdSubmodule); + }); + + it('should produce a valid EID from decode output via createEidsArray', () => { + // Simulate the full Prebid pipeline: + // 1. decode() returns { locId: "string" } + // 2. Prebid extracts idObj["locId"] -> the string + // 3. createEidsArray({ locId: "string" }) should produce a valid EID + const stored = { id: TEST_ID, connectionIp: TEST_CONNECTION_IP }; + const decoded = locIdSubmodule.decode(stored); + expect(decoded).to.deep.equal({ locId: TEST_ID }); + + const eids = createEidsArray(decoded); + expect(eids.length).to.equal(1); + expect(eids[0]).to.deep.equal({ + source: 'locid.com', + uids: [{ id: TEST_ID, atype: 1 }] + }); + expect(eids[0].uids[0].atype).to.not.equal(Number('33' + '84')); + }); + + it('should not produce EID when decode returns undefined', () => { + const decoded = locIdSubmodule.decode(null); + expect(decoded).to.be.undefined; + }); + + it('should not produce EID when only stable_cloc is present', () => { + const decoded = locIdSubmodule.decode({ + stable_cloc: 'stable-only-value', + connectionIp: TEST_CONNECTION_IP + }); + expect(decoded).to.be.undefined; + + const eids = createEidsArray({ locId: decoded?.locId }); + expect(eids).to.deep.equal([]); + }); + + it('should not produce EID when tx_cloc is null', () => { + const decoded = locIdSubmodule.decode({ id: null, connectionIp: TEST_CONNECTION_IP }); + expect(decoded).to.be.undefined; + + const eids = createEidsArray({ locId: decoded?.locId }); + expect(eids).to.deep.equal([]); + }); + + it('should not produce EID when tx_cloc is missing', () => { + const decoded = locIdSubmodule.decode({ connectionIp: TEST_CONNECTION_IP }); + expect(decoded).to.be.undefined; + + const eids = createEidsArray({ locId: decoded?.locId }); + expect(eids).to.deep.equal([]); + }); + }); +}); diff --git a/test/spec/modules/loganBidAdapter_spec.js b/test/spec/modules/loganBidAdapter_spec.js index 8b343761a46..944b51cdf51 100644 --- a/test/spec/modules/loganBidAdapter_spec.js +++ b/test/spec/modules/loganBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/loganBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/loganBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; describe('LoganBidAdapter', function () { diff --git a/test/spec/modules/logicadBidAdapter_spec.js b/test/spec/modules/logicadBidAdapter_spec.js index 24cc1faae62..47351f68304 100644 --- a/test/spec/modules/logicadBidAdapter_spec.js +++ b/test/spec/modules/logicadBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/logicadBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/logicadBidAdapter.js'; import * as utils from 'src/utils.js'; describe('LogicadAdapter', function () { @@ -253,12 +253,12 @@ describe('LogicadAdapter', function () { seller: 'https://fledge.ladsp.com', decisionLogicUrl: 'https://fledge.ladsp.com/decision_logic.js', interestGroupBuyers: ['https://fledge.ladsp.com'], - requestedSize: {width: '300', height: '250'}, - allSlotsRequestedSizes: [{width: '300', height: '250'}], - sellerSignals: {signal: 'signal'}, + requestedSize: { width: '300', height: '250' }, + allSlotsRequestedSizes: [{ width: '300', height: '250' }], + sellerSignals: { signal: 'signal' }, sellerTimeout: '500', - perBuyerSignals: {'https://fledge.ladsp.com': {signal: 'signal'}}, - perBuyerCurrencies: {'https://fledge.ladsp.com': 'USD'} + perBuyerSignals: { 'https://fledge.ladsp.com': { signal: 'signal' } }, + perBuyerCurrencies: { 'https://fledge.ladsp.com': 'USD' } } }] }, @@ -440,10 +440,10 @@ describe('LogicadAdapter', function () { describe('getUserSyncs', function () { it('should perform usersync', function () { - let syncs = spec.getUserSyncs({pixelEnabled: false}, [serverResponse]); + let syncs = spec.getUserSyncs({ pixelEnabled: false }, [serverResponse]); expect(syncs).to.have.length(0); - syncs = spec.getUserSyncs({pixelEnabled: true}, [serverResponse]); + syncs = spec.getUserSyncs({ pixelEnabled: true }, [serverResponse]); expect(syncs).to.have.length(1); expect(syncs[0]).to.have.property('type', 'image'); diff --git a/test/spec/modules/loopmeBidAdapter_spec.js b/test/spec/modules/loopmeBidAdapter_spec.js index 56d185b109a..02174bd19d2 100644 --- a/test/spec/modules/loopmeBidAdapter_spec.js +++ b/test/spec/modules/loopmeBidAdapter_spec.js @@ -7,19 +7,23 @@ const bidder = 'loopme'; const mTypes = [ { [BANNER]: { sizes: [[300, 250]] } }, - { [VIDEO]: { - api: [3, 5], - h: 480, - w: 640, - mimes: ['video/mp4'], - plcmt: 4, - protocols: [1, 2, 3, 4, 5, 6, 7, 8] - } }, - { [NATIVE]: { - adTemplate: `##hb_native_asset_id_1## ##hb_native_asset_id_2## ##hb_native_asset_id_3##`, - image: { required: true, sendId: true }, - title: { required: true }, - body: { required: true } } + { + [VIDEO]: { + api: [3, 5], + h: 480, + w: 640, + mimes: ['video/mp4'], + plcmt: 4, + protocols: [1, 2, 3, 4, 5, 6, 7, 8] + } + }, + { + [NATIVE]: { + adTemplate: `##hb_native_asset_id_1## ##hb_native_asset_id_2## ##hb_native_asset_id_3##`, + image: { required: true, sendId: true }, + title: { required: true }, + body: { required: true } + } } ]; @@ -49,7 +53,7 @@ describe('LoopMeBidAdapter', function () { { publisherId: 'publisherId', bundleId: 'bundleId' }, { publisherId: 'publisherId', placementId: 'placementId' }, { publisherId: 'publisherId' } - ].flatMap(params => mTypes.map(mediaTypes => ({ bidder, bidId, mediaTypes, params}))); + ].flatMap(params => mTypes.map(mediaTypes => ({ bidder, bidId, mediaTypes, params }))); validBids.forEach(function (bid) { it('Should return true if bid request valid', function () { diff --git a/test/spec/modules/lotamePanoramaIdSystem_spec.js b/test/spec/modules/lotamePanoramaIdSystem_spec.js index a441ecbdb21..a68458b8d83 100644 --- a/test/spec/modules/lotamePanoramaIdSystem_spec.js +++ b/test/spec/modules/lotamePanoramaIdSystem_spec.js @@ -5,8 +5,8 @@ import { import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; import sinon from 'sinon'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; const responseHeader = { 'Content-Type': 'application/json' }; diff --git a/test/spec/modules/luceadBidAdapter_spec.js b/test/spec/modules/luceadBidAdapter_spec.js index 464a467e9b2..5de70f83982 100755 --- a/test/spec/modules/luceadBidAdapter_spec.js +++ b/test/spec/modules/luceadBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai'; import { spec } from 'modules/luceadBidAdapter.js'; import sinon from 'sinon'; import { newBidder } from 'src/adapters/bidderFactory.js'; -import {deepClone} from 'src/utils.js'; +import { deepClone } from 'src/utils.js'; import * as ajax from 'src/ajax.js'; describe('Lucead Adapter', () => { @@ -120,7 +120,7 @@ describe('Lucead Adapter', () => { ] }; - const serverResponse = {body: serverResponseBody}; + const serverResponse = { body: serverResponseBody }; const bidRequest = { data: JSON.stringify({ @@ -129,7 +129,7 @@ describe('Lucead Adapter', () => { 'bid_requests': [{ 'bid_id': '2d663fdd390b49', 'sizes': [[300, 250], [300, 150]], - 'media_types': {'banner': {'sizes': [[300, 250], [300, 150]]}}, + 'media_types': { 'banner': { 'sizes': [[300, 250], [300, 150]] } }, 'placement_id': '1' }], }), @@ -154,20 +154,22 @@ describe('Lucead Adapter', () => { }); it('should return bid empty response', function () { - const serverResponse = {body: {bids: [{cpm: 0}]}}; - const bidRequest = {data: '{}'}; + const serverResponse = { body: { bids: [{ cpm: 0 }] } }; + const bidRequest = { data: '{}' }; const result = spec.interpretResponse(serverResponse, bidRequest); expect(result.bids[0].ad).to.be.equal(''); expect(result.bids[0].cpm).to.be.equal(0); }); it('should add advertiserDomains', function () { - const bidRequest = {data: JSON.stringify({ - bidder: 'lucead', - params: { - placementId: '1', - } - })}; + const bidRequest = { + data: JSON.stringify({ + bidder: 'lucead', + params: { + placementId: '1', + } + }) + }; const result = spec.interpretResponse(serverResponse, bidRequest); expect(Object.keys(result.bids[0].meta)).to.include.members(['advertiserDomains']); diff --git a/test/spec/modules/lunamediahbBidAdapter_spec.js b/test/spec/modules/lunamediahbBidAdapter_spec.js index 79c9c0d6172..25a59ba32fe 100644 --- a/test/spec/modules/lunamediahbBidAdapter_spec.js +++ b/test/spec/modules/lunamediahbBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/lunamediahbBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/lunamediahbBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; import { getUniqueIdentifierStr } from '../../../src/utils.js'; @@ -432,7 +432,7 @@ describe('LunamediaHBBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -441,9 +441,7 @@ describe('LunamediaHBBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookie.lmgssp.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -452,7 +450,7 @@ describe('LunamediaHBBidAdapter', function () { expect(syncData[0].url).to.equal('https://cookie.lmgssp.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/mabidderBidAdapter_spec.js b/test/spec/modules/mabidderBidAdapter_spec.js index 805ab168f5d..4230dc0a9aa 100644 --- a/test/spec/modules/mabidderBidAdapter_spec.js +++ b/test/spec/modules/mabidderBidAdapter_spec.js @@ -2,7 +2,7 @@ import { expect } from 'chai' import { baseUrl, spec } from 'modules/mabidderBidAdapter.js' import { newBidder } from 'src/adapters/bidderFactory.js' import { BANNER } from '../../../src/mediaTypes.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('mabidderBidAdapter', () => { const adapter = newBidder(spec) diff --git a/test/spec/modules/madvertiseBidAdapter_spec.js b/test/spec/modules/madvertiseBidAdapter_spec.js index 966d5113105..43541b02b5a 100644 --- a/test/spec/modules/madvertiseBidAdapter_spec.js +++ b/test/spec/modules/madvertiseBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {config} from 'src/config'; +import { expect } from 'chai'; +import { config } from 'src/config'; import * as utils from 'src/utils'; -import {spec} from 'modules/madvertiseBidAdapter'; +import { spec } from 'modules/madvertiseBidAdapter'; describe('madvertise adapater', () => { describe('Test validate req', () => { @@ -155,19 +155,21 @@ describe('madvertise adapater', () => { age: 25, } }; - const resp = spec.interpretResponse({body: { - requestId: 'REQUEST_ID', - cpm: 1, - ad: '

I am an ad

', - Width: 320, - height: 50, - creativeId: 'CREATIVE_ID', - dealId: 'DEAL_ID', - ttl: 180, - currency: 'EUR', - netRevenue: true, - adomain: ['madvertise.com'] - }}, {bidId: bid.bidId}); + const resp = spec.interpretResponse({ + body: { + requestId: 'REQUEST_ID', + cpm: 1, + ad: '

I am an ad

', + Width: 320, + height: 50, + creativeId: 'CREATIVE_ID', + dealId: 'DEAL_ID', + ttl: 180, + currency: 'EUR', + netRevenue: true, + adomain: ['madvertise.com'] + } + }, { bidId: bid.bidId }); expect(resp).to.exist.and.to.be.a('array'); expect(resp[0]).to.have.property('requestId', bid.bidId); @@ -197,7 +199,7 @@ describe('madvertise adapater', () => { age: 25, } }; - const resp = spec.interpretResponse({body: null}, {bidId: bid.bidId}); + const resp = spec.interpretResponse({ body: null }, { bidId: bid.bidId }); expect(resp).to.exist.and.to.be.a('array').that.is.empty; }); diff --git a/test/spec/modules/magniteAnalyticsAdapter_spec.js b/test/spec/modules/magniteAnalyticsAdapter_spec.js index 83a5b83f774..c67d6593696 100644 --- a/test/spec/modules/magniteAnalyticsAdapter_spec.js +++ b/test/spec/modules/magniteAnalyticsAdapter_spec.js @@ -2379,12 +2379,12 @@ describe('magnite analytics adapter', function () { it('adjusts the status according to the status map', () => { const statuses = [ - {code: 0, status: 'no-bid'}, - {code: 100, status: 'error', error: {code: 'request-error', description: 'general error'}}, - {code: 101, status: 'error', error: {code: 'timeout-error', description: 'prebid server timeout'}}, - {code: 200, status: 'rejected'}, - {code: 202, status: 'rejected'}, - {code: 301, status: 'rejected-ipf'} + { code: 0, status: 'no-bid' }, + { code: 100, status: 'error', error: { code: 'request-error', description: 'general error' } }, + { code: 101, status: 'error', error: { code: 'timeout-error', description: 'prebid server timeout' } }, + { code: 200, status: 'rejected' }, + { code: 202, status: 'rejected' }, + { code: 301, status: 'rejected-ipf' } ]; statuses.forEach((info, index) => { checkStatusAgainstCode(info.status, info.code, info.error, index); diff --git a/test/spec/modules/malltvAnalyticsAdapter_spec.js b/test/spec/modules/malltvAnalyticsAdapter_spec.js index 8a88a486a58..cff1d9d4b21 100644 --- a/test/spec/modules/malltvAnalyticsAdapter_spec.js +++ b/test/spec/modules/malltvAnalyticsAdapter_spec.js @@ -115,7 +115,7 @@ describe('Malltv Prebid AnalyticsAdapter Testing', function () { }) describe('#getCachedAuction()', function() { - const existing = {timeoutBids: [{}]} + const existing = { timeoutBids: [{}] } malltvAnalyticsAdapter.cachedAuctions['test_auction_id'] = existing it('should get the existing cached object if it exists', function() { diff --git a/test/spec/modules/mantisBidAdapter_spec.js b/test/spec/modules/mantisBidAdapter_spec.js index 586a6a49181..f3110a6052e 100644 --- a/test/spec/modules/mantisBidAdapter_spec.js +++ b/test/spec/modules/mantisBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec, storage} from 'modules/mantisBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {sfPostMessage, iframePostMessage} from 'modules/mantisBidAdapter'; +import { expect } from 'chai'; +import { spec, storage } from 'modules/mantisBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { sfPostMessage, iframePostMessage } from 'modules/mantisBidAdapter'; describe('MantisAdapter', function () { const adapter = newBidder(spec); @@ -60,7 +60,7 @@ describe('MantisAdapter', function () { } ]); - iframePostMessage({innerHeight: 500, innerWidth: 500}, 'mantis', () => viewed = true); + iframePostMessage({ innerHeight: 500, innerWidth: 500 }, 'mantis', () => viewed = true); sandbox.clock.runAll(); @@ -121,19 +121,19 @@ describe('MantisAdapter', function () { ]; it('gdpr consent not required', function () { - const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: false}}); + const request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: false } }); expect(request.url).not.to.include('consent=false'); }); it('gdpr consent required', function () { - const request = spec.buildRequests(bidRequests, {gdprConsent: {gdprApplies: true}}); + const request = spec.buildRequests(bidRequests, { gdprConsent: { gdprApplies: true } }); expect(request.url).to.include('consent=false'); }); it('usp consent', function () { - const request = spec.buildRequests(bidRequests, {uspConsent: 'foobar'}); + const request = spec.buildRequests(bidRequests, { uspConsent: 'foobar' }); expect(request.url).to.include('usp=foobar'); }); @@ -255,7 +255,7 @@ describe('MantisAdapter', function () { ]; let bidderRequest; - const result = spec.interpretResponse(response, {bidderRequest}); + const result = spec.interpretResponse(response, { bidderRequest }); expect(result[0]).to.deep.equal(expectedResponse[0]); }); @@ -296,7 +296,7 @@ describe('MantisAdapter', function () { ]; let bidderRequest; - const result = spec.interpretResponse(response, {bidderRequest}); + const result = spec.interpretResponse(response, { bidderRequest }); expect(result[0]).to.deep.equal(expectedResponse[0]); }); @@ -339,7 +339,7 @@ describe('MantisAdapter', function () { sandbox.stub(storage, 'hasLocalStorage').returns(true); const spy = sandbox.spy(storage, 'setDataInLocalStorage'); - const result = spec.interpretResponse(response, {bidderRequest}); + const result = spec.interpretResponse(response, { bidderRequest }); expect(spy.calledWith('mantis:uuid', 'uuid')); expect(result[0]).to.deep.equal(expectedResponse[0]); @@ -354,7 +354,7 @@ describe('MantisAdapter', function () { }; let bidderRequest; - const result = spec.interpretResponse(response, {bidderRequest}); + const result = spec.interpretResponse(response, { bidderRequest }); expect(result.length).to.equal(0); }); }); diff --git a/test/spec/modules/marsmediaBidAdapter_spec.js b/test/spec/modules/marsmediaBidAdapter_spec.js index 30c68601767..4dc07ecaa8b 100644 --- a/test/spec/modules/marsmediaBidAdapter_spec.js +++ b/test/spec/modules/marsmediaBidAdapter_spec.js @@ -32,13 +32,15 @@ describe('marsmedia adapter tests', function () { }; win = { document: { - visibilityState: 'visible' + visibilityState: 'visible', + documentElement: { + clientWidth: 800, + clientHeight: 600 + } }, location: { href: 'http://location' }, - innerWidth: 800, - innerHeight: 600 }; this.defaultBidderRequest = { 'refererInfo': { @@ -381,7 +383,7 @@ describe('marsmedia adapter tests', function () { 'zoneId': 9999 }, 'mediaTypes': { - 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} + 'banner': { 'sizes': [['400', '500'], ['4n0', '5g0']] } }, 'adUnitCode': 'Unit-Code', 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', @@ -506,6 +508,8 @@ describe('marsmedia adapter tests', function () { context('when element is fully in view', function() { it('returns 100', function() { + sandbox.stub(internal, 'getWindowTop').returns(win); + resetWinDimensions(); Object.assign(element, { width: 600, height: 400 }); const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); const openrtbRequest = JSON.parse(request.data); @@ -530,7 +534,6 @@ describe('marsmedia adapter tests', function () { const request = marsAdapter.buildRequests(this.defaultBidRequestList, this.defaultBidderRequest); const openrtbRequest = JSON.parse(request.data); expect(openrtbRequest.imp[0].ext.viewability).to.equal(75); - internal.getWindowTop.restore(); }); }); diff --git a/test/spec/modules/mathildeadsBidAdapter_spec.js b/test/spec/modules/mathildeadsBidAdapter_spec.js index 05336197872..21b7b4a7d21 100644 --- a/test/spec/modules/mathildeadsBidAdapter_spec.js +++ b/test/spec/modules/mathildeadsBidAdapter_spec.js @@ -432,7 +432,7 @@ describe('MathildeAdsBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -441,9 +441,7 @@ describe('MathildeAdsBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs2.mathilde-ads.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -452,7 +450,7 @@ describe('MathildeAdsBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs2.mathilde-ads.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/mediaConsortiumBidAdapter_spec.js b/test/spec/modules/mediaConsortiumBidAdapter_spec.js index d19e4f861f1..14e3521ad74 100644 --- a/test/spec/modules/mediaConsortiumBidAdapter_spec.js +++ b/test/spec/modules/mediaConsortiumBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { spec, OPTIMIZATIONS_STORAGE_KEY, getOptimizationsFromLocalStorage } from 'modules/mediaConsortiumBidAdapter.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const BANNER_BID = { adUnitCode: 'dfp_ban_atf', @@ -166,7 +166,7 @@ describe('Media Consortium Bid Adapter', function () { } const bids = [BANNER_BID] - const [syncRequest, auctionRequest] = spec.buildRequests(bids, {...bidderRequest, bids}); + const [syncRequest, auctionRequest] = spec.buildRequests(bids, { ...bidderRequest, bids }); expect(syncRequest.data).to.deep.equal(builtSyncRequest) expect(auctionRequest.data).to.deep.equal(builtBidRequest) @@ -215,7 +215,7 @@ describe('Media Consortium Bid Adapter', function () { } const bids = [VIDEO_BID] - const [syncRequest, auctionRequest] = spec.buildRequests(bids, {...bidderRequest, bids}); + const [syncRequest, auctionRequest] = spec.buildRequests(bids, { ...bidderRequest, bids }); expect(syncRequest.data).to.deep.equal(builtSyncRequest) expect(auctionRequest.data).to.deep.equal(builtBidRequest) @@ -264,7 +264,7 @@ describe('Media Consortium Bid Adapter', function () { } const bids = [MULTI_MEDIATYPES_BID] - const [syncRequest, auctionRequest] = spec.buildRequests(bids, {...bidderRequest, bids}); + const [syncRequest, auctionRequest] = spec.buildRequests(bids, { ...bidderRequest, bids }); expect(syncRequest.data).to.deep.equal(builtSyncRequest) expect(auctionRequest.data).to.deep.equal(builtBidRequest) @@ -278,12 +278,12 @@ describe('Media Consortium Bid Adapter', function () { it('should not build a request if optimizations are there for the adunit code', function () { const bids = [BANNER_BID] const optimizations = { - [bids[0].adUnitCode]: {isEnabled: false, expiresAt: Date.now() + 600000} + [bids[0].adUnitCode]: { isEnabled: false, expiresAt: Date.now() + 600000 } } localStorage.setItem(OPTIMIZATIONS_STORAGE_KEY, JSON.stringify(optimizations)) - const requests = spec.buildRequests(bids, {...bidderRequest, bids}); + const requests = spec.buildRequests(bids, { ...bidderRequest, bids }); localStorage.removeItem(OPTIMIZATIONS_STORAGE_KEY) @@ -301,7 +301,7 @@ describe('Media Consortium Bid Adapter', function () { impressions: [{ id: MULTI_MEDIATYPES_WITH_INVALID_VIDEO_CONTEXT.bidId, adUnitCode: MULTI_MEDIATYPES_WITH_INVALID_VIDEO_CONTEXT.adUnitCode, - mediaTypes: {banner: MULTI_MEDIATYPES_WITH_INVALID_VIDEO_CONTEXT.mediaTypes.banner} + mediaTypes: { banner: MULTI_MEDIATYPES_WITH_INVALID_VIDEO_CONTEXT.mediaTypes.banner } }], device: { w: 1200, @@ -330,9 +330,9 @@ describe('Media Consortium Bid Adapter', function () { const invalidVideoBids = [VIDEO_BID_WITH_MISSING_CONTEXT] const multiMediatypesBidWithInvalidVideo = [MULTI_MEDIATYPES_WITH_INVALID_VIDEO_CONTEXT] - expect(spec.buildRequests(invalidVideoBids, {...bidderRequest, bids: invalidVideoBids})).to.be.undefined + expect(spec.buildRequests(invalidVideoBids, { ...bidderRequest, bids: invalidVideoBids })).to.be.undefined - const [syncRequest, auctionRequest] = spec.buildRequests(multiMediatypesBidWithInvalidVideo, {...bidderRequest, bids: multiMediatypesBidWithInvalidVideo}) + const [syncRequest, auctionRequest] = spec.buildRequests(multiMediatypesBidWithInvalidVideo, { ...bidderRequest, bids: multiMediatypesBidWithInvalidVideo }) expect(syncRequest.data).to.deep.equal(builtSyncRequest) expect(auctionRequest.data).to.deep.equal(builtBidRequest) @@ -341,7 +341,7 @@ describe('Media Consortium Bid Adapter', function () { describe('interpretResponse', function () { it('should return an empty array if the response is invalid', function () { - expect(spec.interpretResponse({body: 'INVALID_BODY'}, {})).to.deep.equal([]); + expect(spec.interpretResponse({ body: 'INVALID_BODY' }, {})).to.deep.equal([]); }) it('should return a formatted banner bid', function () { @@ -360,7 +360,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'banner', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '
1
' } }, @@ -428,7 +428,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...', rendering: { video: { @@ -486,7 +486,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...' } }, @@ -525,7 +525,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...' } }, @@ -555,8 +555,8 @@ describe('Media Consortium Bid Adapter', function () { describe('getUserSyncs', function () { it('should return an empty response if the response is invalid or missing data', function () { - expect(spec.getUserSyncs(null, [{body: 'INVALID_BODY'}])).to.be.undefined; - expect(spec.getUserSyncs(null, [{body: 'INVALID_BODY'}, {body: 'INVALID_BODY'}])).to.be.undefined; + expect(spec.getUserSyncs(null, [{ body: 'INVALID_BODY' }])).to.be.undefined; + expect(spec.getUserSyncs(null, [{ body: 'INVALID_BODY' }, { body: 'INVALID_BODY' }])).to.be.undefined; }) it('should return an array of user syncs', function () { @@ -564,9 +564,9 @@ describe('Media Consortium Bid Adapter', function () { { body: { bidders: [ - {type: 'image', url: 'https://test-url.com'}, - {type: 'redirect', url: 'https://test-url.com'}, - {type: 'iframe', url: 'https://test-url.com'} + { type: 'image', url: 'https://test-url.com' }, + { type: 'redirect', url: 'https://test-url.com' }, + { type: 'iframe', url: 'https://test-url.com' } ] } }, @@ -576,9 +576,9 @@ describe('Media Consortium Bid Adapter', function () { ] const formattedUserSyncs = [ - {type: 'image', url: 'https://test-url.com'}, - {type: 'image', url: 'https://test-url.com'}, - {type: 'iframe', url: 'https://test-url.com'} + { type: 'image', url: 'https://test-url.com' }, + { type: 'image', url: 'https://test-url.com' }, + { type: 'iframe', url: 'https://test-url.com' } ] expect(spec.getUserSyncs(null, serverResponses)).to.deep.equal(formattedUserSyncs); @@ -601,7 +601,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...', rendering: { video: { @@ -659,7 +659,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...', rendering: { video: { @@ -720,7 +720,7 @@ describe('Media Consortium Bid Adapter', function () { creative: { id: 'CREATIVE_ID', mediaType: 'video', - size: {width: 320, height: 250}, + size: { width: 320, height: 250 }, markup: '...' } }, diff --git a/test/spec/modules/mediabramaBidAdapter_spec.js b/test/spec/modules/mediabramaBidAdapter_spec.js index 74c2ac48e5a..44aae9ccb67 100644 --- a/test/spec/modules/mediabramaBidAdapter_spec.js +++ b/test/spec/modules/mediabramaBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/mediabramaBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/mediabramaBidAdapter.js'; import { BANNER } from '../../../src/mediaTypes.js'; import * as utils from '../../../src/utils.js'; diff --git a/test/spec/modules/mediaeyesBidAdapter_spec.js b/test/spec/modules/mediaeyesBidAdapter_spec.js index 33c5981c530..4ccc85058b2 100644 --- a/test/spec/modules/mediaeyesBidAdapter_spec.js +++ b/test/spec/modules/mediaeyesBidAdapter_spec.js @@ -114,7 +114,7 @@ describe('mediaeyes adapter', function () { } let bidderRequest; - const result = spec.interpretResponse(response, {bidderRequest}); + const result = spec.interpretResponse(response, { bidderRequest }); expect(result.length).to.equal(0); }); }) diff --git a/test/spec/modules/mediaforceBidAdapter_spec.js b/test/spec/modules/mediaforceBidAdapter_spec.js index 6ae86dc0801..887acb3fe8d 100644 --- a/test/spec/modules/mediaforceBidAdapter_spec.js +++ b/test/spec/modules/mediaforceBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {assert} from 'chai'; -import {spec, resolveFloor} from 'modules/mediaforceBidAdapter.js'; +import { assert } from 'chai'; +import { spec, resolveFloor } from 'modules/mediaforceBidAdapter.js'; import * as utils from '../../../src/utils.js'; import { getDNT } from 'libraries/dnt/index.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; describe('mediaforce bid adapter', function () { let sandbox; @@ -44,7 +44,7 @@ describe('mediaforce bid adapter', function () { it('should return false when valid params are not passed', function () { const bid = utils.deepClone(defaultBid); - bid.params = {placement_id: '', publisher_id: ''}; + bid.params = { placement_id: '', publisher_id: '' }; assert.equal(spec.isBidRequestValid(bid), false); }); @@ -55,7 +55,7 @@ describe('mediaforce bid adapter', function () { sizes: [[300, 250]] } }; - bid.params = {publisher_id: 2, placement_id: '123'}; + bid.params = { publisher_id: 2, placement_id: '123' }; assert.equal(spec.isBidRequestValid(bid), true); }); }); @@ -143,7 +143,7 @@ describe('mediaforce bid adapter', function () { }, site: { id: defaultBid.params.publisher_id, - publisher: {id: defaultBid.params.publisher_id}, + publisher: { id: defaultBid.params.publisher_id }, ref: encodeURIComponent(refererInfo.ref), page: pageUrl, }, @@ -162,14 +162,14 @@ describe('mediaforce bid adapter', function () { transactionId: defaultBid.ortb2Imp.ext.tid, } }, - banner: {w: 300, h: 250}, + banner: { w: 300, h: 250 }, native: { ver: '1.2', request: { assets: [ - {id: 1, title: {len: 800}, required: 1}, - {id: 3, img: {w: 300, h: 250, type: 3}, required: 1}, - {id: 5, data: {type: 1}, required: 0} + { id: 1, title: { len: 800 }, required: 1 }, + { id: 3, img: { w: 300, h: 250, type: 3 }, required: 1 }, + { id: 5, data: { type: 1 }, required: 0 } ], context: 1, plcmttype: 1, @@ -213,10 +213,10 @@ describe('mediaforce bid adapter', function () { placement_id: '203', transactionId: '8df76688-1618-417a-87b1-60ad046841c9' } - ].map(({publisher_id, placement_id, transactionId}) => { + ].map(({ publisher_id, placement_id, transactionId }) => { return { bidder: 'mediaforce', - params: {publisher_id, placement_id}, + params: { publisher_id, placement_id }, mediaTypes: { banner: { sizes: [[300, 250], [600, 400]] @@ -330,7 +330,7 @@ describe('mediaforce bid adapter', function () { const [request] = spec.buildRequests([bid]); const data = JSON.parse(request.data); - assert.deepEqual(data.imp[0].banner, {w: 300, h: 600, format: [{w: 300, h: 250}]}); + assert.deepEqual(data.imp[0].banner, { w: 300, h: 600, format: [{ w: 300, h: 250 }] }); }); it('should skip banner with empty sizes', function () { @@ -370,7 +370,7 @@ describe('mediaforce bid adapter', function () { }, site: { id: 'pub123', - publisher: {id: 'pub123'}, + publisher: { id: 'pub123' }, ref: encodeURIComponent(refererInfo.ref), page: pageUrl, }, @@ -389,7 +389,7 @@ describe('mediaforce bid adapter', function () { transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' } }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, + banner: { w: 300, h: 250, format: [{ w: 600, h: 400 }] }, }, { tagid: '203', secure: secure, @@ -399,7 +399,7 @@ describe('mediaforce bid adapter', function () { transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' } }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, + banner: { w: 300, h: 250, format: [{ w: 600, h: 400 }] }, }, { tagid: '203', secure: secure, @@ -409,7 +409,7 @@ describe('mediaforce bid adapter', function () { transactionId: '8df76688-1618-417a-87b1-60ad046841c9' } }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, + banner: { w: 300, h: 250, format: [{ w: 600, h: 400 }] }, }] } }, @@ -426,7 +426,7 @@ describe('mediaforce bid adapter', function () { }, site: { id: 'pub124', - publisher: {id: 'pub124'}, + publisher: { id: 'pub124' }, ref: encodeURIComponent(refererInfo.ref), page: pageUrl, }, @@ -445,7 +445,7 @@ describe('mediaforce bid adapter', function () { transactionId: 'd45dd707-a418-42ec-b8a7-b70a6c6fab0b' } }, - banner: {w: 300, h: 250, format: [{w: 600, h: 400}]}, + banner: { w: 300, h: 250, format: [{ w: 600, h: 400 }] }, }] } } @@ -527,20 +527,20 @@ describe('mediaforce bid adapter', function () { ext: { advertiser_name: 'MediaForce', native: { - link: {url: nativeLink}, + link: { url: nativeLink }, assets: [{ id: 1, - title: {text: titleText}, + title: { text: titleText }, required: 1 }, { id: 3, img: imgData }, { id: 5, - data: {value: sponsoredByValue} + data: { value: sponsoredByValue } }, { id: 4, - data: {value: bodyValue} + data: { value: bodyValue } }], imptrackers: [nativeTracker], ver: '1' @@ -603,20 +603,20 @@ describe('mediaforce bid adapter', function () { const bodyValue = 'Drivers With No Tickets In 3 Years Should Do This On June'; const adm = JSON.stringify({ native: { - link: {url: nativeLink}, + link: { url: nativeLink }, assets: [{ id: 1, - title: {text: titleText}, + title: { text: titleText }, required: 1 }, { id: 3, img: imgData }, { id: 5, - data: {value: sponsoredByValue} + data: { value: sponsoredByValue } }, { id: 4, - data: {value: bodyValue} + data: { value: bodyValue } }], imptrackers: [nativeTracker], ver: '1' diff --git a/test/spec/modules/mediafuseBidAdapter_spec.js b/test/spec/modules/mediafuseBidAdapter_spec.js index ff806d91f2c..e446a1c1138 100644 --- a/test/spec/modules/mediafuseBidAdapter_spec.js +++ b/test/spec/modules/mediafuseBidAdapter_spec.js @@ -5,7 +5,7 @@ import * as bidderFactory from 'src/adapters/bidderFactory.js'; import { auctionManager } from 'src/auctionManager.js'; import { deepClone } from 'src/utils.js'; import { config } from 'src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const ENDPOINT = 'https://ib.adnxs.com/ut/v3/prebid'; @@ -98,7 +98,7 @@ describe('MediaFuseAdapter', function () { const payload = JSON.parse(request.data); expect(payload.tags[0].private_sizes).to.exist; - expect(payload.tags[0].private_sizes).to.deep.equal([{width: 300, height: 250}]); + expect(payload.tags[0].private_sizes).to.deep.equal([{ width: 300, height: 250 }]); }); it('should add publisher_id in request', function() { @@ -177,7 +177,7 @@ describe('MediaFuseAdapter', function () { it('should populate the ad_types array on outstream requests', function () { const bidRequest = Object.assign({}, bidRequests[0]); bidRequest.mediaTypes = {}; - bidRequest.mediaTypes.video = {context: 'outstream'}; + bidRequest.mediaTypes.video = { context: 'outstream' }; const request = spec.buildRequests([bidRequest]); const payload = JSON.parse(request.data); @@ -313,7 +313,7 @@ describe('MediaFuseAdapter', function () { expect(payload.user).to.exist; expect(payload.user).to.deep.equal({ external_uid: '123', - segments: [{id: 123}, {id: 987, value: 876}] + segments: [{ id: 123 }, { id: 987, value: 876 }] }); }); @@ -590,22 +590,22 @@ describe('MediaFuseAdapter', function () { { mediaType: 'native', nativeParams: { - title: {required: true}, - body: {required: true}, - body2: {required: true}, - image: {required: true, sizes: [100, 100]}, - icon: {required: true}, - cta: {required: false}, - rating: {required: true}, - sponsoredBy: {required: true}, - privacyLink: {required: true}, - displayUrl: {required: true}, - address: {required: true}, - downloads: {required: true}, - likes: {required: true}, - phone: {required: true}, - price: {required: true}, - salePrice: {required: true} + title: { required: true }, + body: { required: true }, + body2: { required: true }, + image: { required: true, sizes: [100, 100] }, + icon: { required: true }, + cta: { required: false }, + rating: { required: true }, + sponsoredBy: { required: true }, + privacyLink: { required: true }, + displayUrl: { required: true }, + address: { required: true }, + downloads: { required: true }, + likes: { required: true }, + phone: { required: true }, + price: { required: true }, + salePrice: { required: true } } } ); @@ -614,22 +614,22 @@ describe('MediaFuseAdapter', function () { const payload = JSON.parse(request.data); expect(payload.tags[0].native.layouts[0]).to.deep.equal({ - title: {required: true}, - description: {required: true}, - desc2: {required: true}, - main_image: {required: true, sizes: [{ width: 100, height: 100 }]}, - icon: {required: true}, - ctatext: {required: false}, - rating: {required: true}, - sponsored_by: {required: true}, - privacy_link: {required: true}, - displayurl: {required: true}, - address: {required: true}, - downloads: {required: true}, - likes: {required: true}, - phone: {required: true}, - price: {required: true}, - saleprice: {required: true}, + title: { required: true }, + description: { required: true }, + desc2: { required: true }, + main_image: { required: true, sizes: [{ width: 100, height: 100 }] }, + icon: { required: true }, + ctatext: { required: false }, + rating: { required: true }, + sponsored_by: { required: true }, + privacy_link: { required: true }, + displayurl: { required: true }, + address: { required: true }, + downloads: { required: true }, + likes: { required: true }, + phone: { required: true }, + price: { required: true }, + saleprice: { required: true }, privacy_supported: true }); expect(payload.tags[0].hb_source).to.equal(1); @@ -649,14 +649,14 @@ describe('MediaFuseAdapter', function () { let request = spec.buildRequests([bidRequest]); let payload = JSON.parse(request.data); - expect(payload.tags[0].sizes).to.deep.equal([{width: 150, height: 100}, {width: 300, height: 250}]); + expect(payload.tags[0].sizes).to.deep.equal([{ width: 150, height: 100 }, { width: 300, height: 250 }]); delete bidRequest.sizes; request = spec.buildRequests([bidRequest]); payload = JSON.parse(request.data); - expect(payload.tags[0].sizes).to.deep.equal([{width: 1, height: 1}]); + expect(payload.tags[0].sizes).to.deep.equal([{ width: 1, height: 1 }]); }); it('should convert keyword params to proper form and attaches to request', function () { @@ -673,7 +673,7 @@ describe('MediaFuseAdapter', function () { singleValNum: 123, emptyStr: '', emptyArr: [''], - badValue: {'foo': 'bar'} // should be dropped + badValue: { 'foo': 'bar' } // should be dropped } } } @@ -748,7 +748,7 @@ describe('MediaFuseAdapter', function () { bidderRequest.bids = bidRequests; const request = spec.buildRequests(bidRequests, bidderRequest); - expect(request.options).to.deep.equal({withCredentials: true}); + expect(request.options).to.deep.equal({ withCredentials: true }); const payload = JSON.parse(request.data); expect(payload.gdpr_consent).to.exist; @@ -902,7 +902,7 @@ describe('MediaFuseAdapter', function () { .returns(true); const request = spec.buildRequests([bidRequest]); - expect(request.options.customHeaders).to.deep.equal({'X-Is-Test': 1}); + expect(request.options.customHeaders).to.deep.equal({ 'X-Is-Test': 1 }); config.getConfig.restore(); }); @@ -1136,7 +1136,7 @@ describe('MediaFuseAdapter', function () { adUnitCode: 'code' }] }; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); @@ -1187,7 +1187,7 @@ describe('MediaFuseAdapter', function () { }; let bidderRequest; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); @@ -1220,7 +1220,7 @@ describe('MediaFuseAdapter', function () { }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).to.have.property('vastXml'); expect(result[0]).to.have.property('vastImpUrl'); expect(result[0]).to.have.property('mediaType', 'video'); @@ -1255,7 +1255,7 @@ describe('MediaFuseAdapter', function () { }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).to.have.property('vastUrl'); expect(result[0]).to.have.property('vastImpUrl'); expect(result[0]).to.have.property('mediaType', 'video'); @@ -1295,7 +1295,7 @@ describe('MediaFuseAdapter', function () { }] }; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result[0]).to.have.property('vastUrl'); expect(result[0].video.context).to.equal('adpod'); expect(result[0].video.durationSeconds).to.equal(30); @@ -1344,7 +1344,7 @@ describe('MediaFuseAdapter', function () { }] } - const result = spec.interpretResponse({ body: response1 }, {bidderRequest}); + const result = spec.interpretResponse({ body: response1 }, { bidderRequest }); expect(result[0].native.title).to.equal('Native Creative'); expect(result[0].native.body).to.equal('Cool description great stuff'); expect(result[0].native.cta).to.equal('Do it'); @@ -1372,7 +1372,7 @@ describe('MediaFuseAdapter', function () { }] }; - const result = spec.interpretResponse({ body: outstreamResponse }, {bidderRequest}); + const result = spec.interpretResponse({ body: outstreamResponse }, { bidderRequest }); expect(result[0].renderer.config).to.deep.equal( bidderRequest.bids[0].renderer.options ); @@ -1400,7 +1400,7 @@ describe('MediaFuseAdapter', function () { } }] } - const result = spec.interpretResponse({ body: responseWithDeal }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseWithDeal }, { bidderRequest }); expect(Object.keys(result[0].mediafuse)).to.include.members(['buyerMemberId', 'dealPriority', 'dealCode']); expect(result[0].video.dealTier).to.equal(5); }); @@ -1415,7 +1415,7 @@ describe('MediaFuseAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseAdvertiserId }, { bidderRequest }); expect(Object.keys(result[0].meta)).to.include.members(['advertiserId']); }); @@ -1429,7 +1429,7 @@ describe('MediaFuseAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: responseBrandId }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseBrandId }, { bidderRequest }); expect(Object.keys(result[0].meta)).to.include.members(['brandId']); }); @@ -1443,7 +1443,7 @@ describe('MediaFuseAdapter', function () { adUnitCode: 'code' }] } - const result = spec.interpretResponse({ body: responseAdvertiserId }, {bidderRequest}); + const result = spec.interpretResponse({ body: responseAdvertiserId }, { bidderRequest }); expect(Object.keys(result[0].meta)).to.include.members(['advertiserDomains']); expect(Object.keys(result[0].meta.advertiserDomains)).to.deep.equal([]); }); diff --git a/test/spec/modules/mediagoBidAdapter_spec.js b/test/spec/modules/mediagoBidAdapter_spec.js index 8c4c6bc0f3a..c69841abb0e 100644 --- a/test/spec/modules/mediagoBidAdapter_spec.js +++ b/test/spec/modules/mediagoBidAdapter_spec.js @@ -141,6 +141,19 @@ describe('mediago:BidAdapterTests', function () { expect(req_data.imp).to.have.lengthOf(1); }); + it('mediago:validate_transactionId_in_request', function () { + request = spec.buildRequests(bidRequestData.bids, bidRequestData); + const req_data = JSON.parse(request.data); + expect(req_data.imp[0].ext.transactionId).to.equal('7b26fdae-96e6-4c35-a18b-218dda11397d'); + }); + + it('mediago:validate_pbjs_source_and_version_in_request', function () { + request = spec.buildRequests(bidRequestData.bids, bidRequestData); + const req_data = JSON.parse(request.data); + expect(req_data.ext.pbjsversion).to.be.a('string'); + expect(req_data.ext.pbjsversion.length).to.be.above(0); + }); + describe('mediago: buildRequests', function() { describe('getPmgUID function', function() { let sandbox; diff --git a/test/spec/modules/mediaimpactBidAdapter_spec.js b/test/spec/modules/mediaimpactBidAdapter_spec.js index 518397b11f8..5db6f9c6611 100644 --- a/test/spec/modules/mediaimpactBidAdapter_spec.js +++ b/test/spec/modules/mediaimpactBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH} from 'modules/mediaimpactBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH } from 'modules/mediaimpactBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as miUtils from 'libraries/mediaImpactUtils/index.js'; const BIDDER_CODE = 'mediaimpact'; @@ -144,9 +144,9 @@ describe('MediaimpactAdapter', function () { 'advertiserDomains': ['test.domain'] }, 'syncs': [ - {'type': 'image', 'url': 'https://test.domain/tracker_1.gif'}, - {'type': 'image', 'url': 'https://test.domain/tracker_2.gif'}, - {'type': 'image', 'url': 'https://test.domain/tracker_3.gif'} + { 'type': 'image', 'url': 'https://test.domain/tracker_1.gif' }, + { 'type': 'image', 'url': 'https://test.domain/tracker_2.gif' }, + { 'type': 'image', 'url': 'https://test.domain/tracker_3.gif' } ], 'winNotification': [ { @@ -154,7 +154,7 @@ describe('MediaimpactAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 @@ -179,7 +179,7 @@ describe('MediaimpactAdapter', function () { expect(result[0].currency).to.equal('USD'); expect(result[0].ttl).to.equal(60); expect(result[0].meta.advertiserDomains).to.deep.equal(['test.domain']); - expect(result[0].winNotification[0]).to.deep.equal({'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': {'ad': [{'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'}], 'unit_id': 1234, 'site_id': 123}}); + expect(result[0].winNotification[0]).to.deep.equal({ 'method': 'POST', 'path': '/hb/bid_won?test=1', 'data': { 'ad': [{ 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' }], 'unit_id': 1234, 'site_id': 123 } }); }); }); @@ -227,7 +227,7 @@ describe('MediaimpactAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 0.01, 'nurl': 'http://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 @@ -268,9 +268,9 @@ describe('MediaimpactAdapter', function () { 'advertiserDomains': ['test.domain'] }, 'syncs': [ - {'type': 'image', 'link': 'https://test.domain/tracker_1.gif'}, - {'type': 'image', 'link': 'https://test.domain/tracker_2.gif'}, - {'type': 'image', 'link': 'https://test.domain/tracker_3.gif'} + { 'type': 'image', 'link': 'https://test.domain/tracker_1.gif' }, + { 'type': 'image', 'link': 'https://test.domain/tracker_2.gif' }, + { 'type': 'image', 'link': 'https://test.domain/tracker_3.gif' } ], 'winNotification': [ { @@ -278,7 +278,7 @@ describe('MediaimpactAdapter', function () { 'path': '/hb/bid_won?test=1', 'data': { 'ad': [ - {'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/'} + { 'dsp': 8, 'id': 800008, 'cost': 1.0e-5, 'nurl': 'https://test.domain/' } ], 'unit_id': 1234, 'site_id': 123 diff --git a/test/spec/modules/mediakeysBidAdapter_spec.js b/test/spec/modules/mediakeysBidAdapter_spec.js index d724b0891b1..d3aa61aacc7 100644 --- a/test/spec/modules/mediakeysBidAdapter_spec.js +++ b/test/spec/modules/mediakeysBidAdapter_spec.js @@ -303,7 +303,7 @@ describe('mediakeysBidAdapter', function () { it('should log errors and ignore misformated assets', function() { const bidRequests = [utils.deepClone(bidNative)]; delete bidRequests[0].nativeParams.title.len; - bidRequests[0].nativeParams.unregistred = {required: true}; + bidRequests[0].nativeParams.unregistred = { required: true }; const bidderRequestCopy = utils.deepClone(bidderRequest); bidderRequestCopy.bids = bidRequests; @@ -593,7 +593,7 @@ describe('mediakeysBidAdapter', function () { }; const bidRequests = [utils.deepClone(bid)]; - const request = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}); + const request = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }); const data = request.data; expect(data.site.domain).to.equal('domain.example'); expect(data.site.cat[0]).to.equal('IAB12'); diff --git a/test/spec/modules/medianetAnalyticsAdapter_spec.js b/test/spec/modules/medianetAnalyticsAdapter_spec.js index e3933a966ac..fa83d593a92 100644 --- a/test/spec/modules/medianetAnalyticsAdapter_spec.js +++ b/test/spec/modules/medianetAnalyticsAdapter_spec.js @@ -1,14 +1,14 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import medianetAnalytics from 'modules/medianetAnalyticsAdapter.js'; import * as utils from 'src/utils.js'; -import {EVENTS, REJECTION_REASON} from 'src/constants.js'; +import { EVENTS, REJECTION_REASON } from 'src/constants.js'; import * as events from 'src/events.js'; -import {clearEvents} from 'src/events.js'; -import {deepAccess} from 'src/utils.js'; +import { clearEvents } from 'src/events.js'; +import { deepAccess } from 'src/utils.js'; import 'src/prebid.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; -import {getGlobal} from 'src/prebidGlobal.js'; +import { getGlobal } from 'src/prebidGlobal.js'; import sinon from "sinon"; import * as mnUtils from '../../../libraries/medianetUtils/utils.js'; @@ -36,7 +36,7 @@ function createBidResponse(bidderCode, requestId, cpm, adId = '3e6e4bce5c8fb3') requestId, mediaType: 'banner', source: 'client', - ext: {pvid: 123, crid: '321'}, + ext: { pvid: 123, crid: '321' }, no_bid: false, cpm, ad: 'AD_CODE', @@ -47,7 +47,7 @@ function createBidResponse(bidderCode, requestId, cpm, adId = '3e6e4bce5c8fb3') dfp_id: 'div-gpt-ad-1460505748561-0', originalCpm: cpm, originalCurrency: 'USD', - floorData: {floorValue: 1.10, floorRule: 'banner'}, + floorData: { floorValue: 1.10, floorRule: 'banner' }, auctionId: '8e0d5245-deb3-406c-96ca-9b609e077ff7', snm: 'SUCCESS', responseTimestamp: 1584563606009, @@ -71,7 +71,7 @@ function createBidResponse(bidderCode, requestId, cpm, adId = '3e6e4bce5c8fb3') hb_format: 'banner', prebid_test: 1 }, - params: [{cid: 'test123', crid: '451466393'}] + params: [{ cid: 'test123', crid: '451466393' }] }; } @@ -81,7 +81,7 @@ function createBidRequest(bidderCode, auctionId, bidId, adUnits) { auctionId, bids: adUnits.map(adUnit => ({ bidder: bidderCode, - params: {cid: 'TEST_CID', crid: '451466393'}, + params: { cid: 'TEST_CID', crid: '451466393' }, mediaTypes: adUnit.mediaTypes, adUnitCode: adUnit.code, sizes: [(adUnit.mediaTypes.banner?.sizes || []), (adUnit.mediaTypes.native?.image?.sizes || []), (adUnit.mediaTypes.video?.playerSize || [])], @@ -100,7 +100,7 @@ function createNoBid(bidder, params) { return { bidder, params, - mediaTypes: {banner: {sizes: [[300, 250]], ext: ['asdads']}}, + mediaTypes: { banner: { sizes: [[300, 250]], ext: ['asdads'] } }, adUnitCode: 'div-gpt-ad-1460505748561-0', transactionId: '303fa0c6-682f-4aea-8e4a-dc68f0d5c7d5', sizes: [[300, 250], [300, 600]], @@ -166,29 +166,29 @@ function createBidWon(bidderCode, adId, requestId, cpm) { prebid_test: 1 }, status: 'rendered', - params: [{cid: 'test123', crid: '451466393'}] + params: [{ cid: 'test123', crid: '451466393' }] }; } -const BANNER_AD_UNIT = {code: 'div-gpt-ad-1460505748561-0', mediaTypes: {banner: {sizes: [[300, 250]]}}}; +const BANNER_AD_UNIT = { code: 'div-gpt-ad-1460505748561-0', mediaTypes: { banner: { sizes: [[300, 250]] } } }; const VIDEO_AD_UNIT = { code: 'div-gpt-ad-1460505748561-0', - mediaTypes: {video: {playerSize: [640, 480], context: 'outstream'}} + mediaTypes: { video: { playerSize: [640, 480], context: 'outstream' } } }; const INSTREAM_VIDEO_AD_UNIT = { code: 'div-gpt-ad-1460505748561-0', - mediaTypes: {video: {playerSize: [640, 480], context: 'instream'}} + mediaTypes: { video: { playerSize: [640, 480], context: 'instream' } } }; const BANNER_NATIVE_AD_UNIT = { code: 'div-gpt-ad-1460505748561-0', - mediaTypes: {banner: {sizes: [[300, 250]]}, native: {image: {required: true, sizes: [150, 50]}}} + mediaTypes: { banner: { sizes: [[300, 250]] }, native: { image: { required: true, sizes: [150, 50] } } } }; const BANNER_NATIVE_VIDEO_AD_UNIT = { code: 'div-gpt-ad-1460505748561-0', mediaTypes: { - banner: {sizes: [[300, 250]]}, - video: {playerSize: [640, 480], context: 'outstream'}, - native: {image: {required: true, sizes: [150, 50]}, title: {required: true, len: 80}} + banner: { sizes: [[300, 250]] }, + video: { playerSize: [640, 480], context: 'outstream' }, + native: { image: { required: true, sizes: [150, 50] }, title: { required: true, len: 80 } } } }; @@ -215,7 +215,7 @@ const MOCK = { auctionId: '8e0d5245-deb3-406c-96ca-9b609e077ff7', timestamp: 1584563605739, timeout: 6000, - bidderRequests: [{bids: [{floorData: {enforcements: {enforceJS: true}}}]}] + bidderRequests: [{ bids: [{ floorData: { enforcements: { enforceJS: true } } }] }] }, MNET_BID_REQUESTED: createBidRequest('medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', '28248b0e6aece2', [BANNER_NATIVE_VIDEO_AD_UNIT]), MNET_BID_RESPONSE: createBidResponse('medianet', '28248b0e6aece2', 2.299), @@ -234,14 +234,14 @@ const MOCK = { MULTI_BID_RESPONSES: [ createBidResponse('medianet', '28248b0e6aece2', 2.299, '3e6e4bce5c8fb3'), Object.assign(createBidResponse('medianet', '28248b0e6aebecc', 3.299, '3e6e4bce5c8fb4'), - {originalBidder: 'bidA2', originalRequestId: '28248b0e6aece2'}), + { originalBidder: 'bidA2', originalRequestId: '28248b0e6aece2' }), ], - MNET_NO_BID: createNoBid('medianet', {cid: 'test123', crid: '451466393', site: {}}), + MNET_NO_BID: createNoBid('medianet', { cid: 'test123', crid: '451466393', site: {} }), MNET_BID_TIMEOUT: createBidTimeout('28248b0e6aece2', 'medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', [{ cid: 'test123', crid: '451466393', site: {} - }, {cid: '8CUX0H51P', crid: '451466393', site: {}}]), + }, { cid: '8CUX0H51P', crid: '451466393', site: {} }]), AUCTION_END: { auctionId: '8e0d5245-deb3-406c-96ca-9b609e077ff7', auctionEnd: 1584563605739, @@ -266,11 +266,11 @@ const MOCK = { hb_bidder_medianet: 'medianet' } }, - NO_BID_SET_TARGETING: {'div-gpt-ad-1460505748561-0': {}}, + NO_BID_SET_TARGETING: { 'div-gpt-ad-1460505748561-0': {} }, // S2S mocks MNET_S2S_BID_REQUESTED: createS2SBidRequest('medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', '28248b0e6aece2', [BANNER_AD_UNIT]), MNET_S2S_BID_RESPONSE: createS2SBidResponse('medianet', '28248b0e6aece2', 2.299), - MNET_S2S_BID_WON: Object.assign({}, createBidWon('medianet', '3e6e4bce5c8fb3', '28248b0e6aece2', 2.299), {source: 's2s'}), + MNET_S2S_BID_WON: Object.assign({}, createBidWon('medianet', '3e6e4bce5c8fb3', '28248b0e6aece2', 2.299), { source: 's2s' }), MNET_S2S_SET_TARGETING: { 'div-gpt-ad-1460505748561-0': { prebid_test: '1', @@ -322,15 +322,15 @@ function waitForPromiseResolve(promise) { } function performNoBidAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(NO_BID, MOCK.MNET_NO_BID); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_BID_REQUESTED] })); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); } function performBidWonAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.MNET_BID_RESPONSE); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); @@ -338,63 +338,63 @@ function performBidWonAuction() { } function performBidTimeoutAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(BID_TIMEOUT, MOCK.MNET_BID_TIMEOUT); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_BID_REQUESTED] })); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); } function performAuctionWithSameRequestIdBids(bidRespArray) { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); bidRespArray.forEach(bidResp => events.emit(BID_RESPONSE, bidResp)); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_BID_REQUESTED] })); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); events.emit(BID_WON, MOCK.MNET_BID_WON); } function performAuctionNoWin() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); MOCK.COMMON_REQ_ID_BID_REQUESTS.forEach(bidReq => events.emit(BID_REQUESTED, bidReq)); MOCK.COMMON_REQ_ID_BID_RESPONSES.forEach(bidResp => events.emit(BID_RESPONSE, bidResp)); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: MOCK.COMMON_REQ_ID_BID_REQUESTS})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: MOCK.COMMON_REQ_ID_BID_REQUESTS })); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); } function performMultiBidAuction() { const bidRequest = createBidRequest('medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', '28248b0e6aece2', [BANNER_AD_UNIT]); - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, bidRequest); MOCK.MULTI_BID_RESPONSES.forEach(bidResp => events.emit(BID_RESPONSE, bidResp)); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [bidRequest]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [bidRequest] })); events.emit(SET_TARGETING, MOCK.MNET_SET_TARGETING); } function performBidRejectedAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.MNET_BID_RESPONSE); events.emit(BID_REJECTED, Object.assign({}, MOCK.MNET_BID_RESPONSE, { rejectionReason: REJECTION_REASON.FLOOR_NOT_MET, })); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_BID_REQUESTED] })); } function performS2SAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_S2S_BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.MNET_S2S_BID_RESPONSE); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_S2S_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_S2S_BID_REQUESTED] })); events.emit(SET_TARGETING, MOCK.MNET_S2S_SET_TARGETING); events.emit(BID_WON, MOCK.MNET_S2S_BID_WON); } function performCurrencyConversionAuction() { - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.MNET_JPY_BID_RESPONSE); - events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, {bidderRequests: [MOCK.MNET_BID_REQUESTED]})); + events.emit(AUCTION_END, Object.assign({}, MOCK.AUCTION_END, { bidderRequests: [MOCK.MNET_BID_REQUESTED] })); } describe('Media.net Analytics Adapter', function () { @@ -464,7 +464,7 @@ describe('Media.net Analytics Adapter', function () { }); it('should generate valid tracking URL for video bids', function () { - const VIDEO_AUCTION = Object.assign({}, MOCK.AUCTION_INIT, {adUnits: [INSTREAM_VIDEO_AD_UNIT]}); + const VIDEO_AUCTION = Object.assign({}, MOCK.AUCTION_INIT, { adUnits: [INSTREAM_VIDEO_AD_UNIT] }); const VIDEO_BID_REQUESTED = createBidRequest('medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', '28248b0e6aece2', [INSTREAM_VIDEO_AD_UNIT]); const videoBidResponse = Object.assign({}, MOCK.MNET_BID_RESPONSE, { mediaType: 'video', @@ -511,7 +511,7 @@ describe('Media.net Analytics Adapter', function () { }); it('should return error tracker when bidrequest is missing', function () { - const VIDEO_AUCTION = Object.assign({}, MOCK.AUCTION_INIT, {adUnits: [INSTREAM_VIDEO_AD_UNIT]}); + const VIDEO_AUCTION = Object.assign({}, MOCK.AUCTION_INIT, { adUnits: [INSTREAM_VIDEO_AD_UNIT] }); const VIDEO_BID_REQUESTED = createBidRequest('medianet', '8e0d5245-deb3-406c-96ca-9b609e077ff7', '28248b0e6aece2', [INSTREAM_VIDEO_AD_UNIT]); const videoBidResponse = Object.assign({}, MOCK.MNET_BID_RESPONSE, { mediaType: 'video', @@ -632,7 +632,7 @@ describe('Media.net Analytics Adapter', function () { bidCopy.cpm = bidCopy.originalCpm * 0.8; // Simulate bidCpmAdjustment // Emit events to simulate an auction - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_BID_REQUESTED); events.emit(BID_RESPONSE, bidCopy); events.emit(AUCTION_END, MOCK.AUCTION_END); @@ -738,7 +738,7 @@ describe('Media.net Analytics Adapter', function () { it('should set serverLatencyMillis and filtered pbsExt for S2S bids on AUCTION_END', function (done) { // enable analytics and start an S2S auction flow medianetAnalytics.clearlogsQueue(); - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_S2S_BID_REQUESTED); events.emit(BID_RESPONSE, MOCK.MNET_S2S_BID_RESPONSE); @@ -776,7 +776,7 @@ describe('Media.net Analytics Adapter', function () { const auctionId = MOCK.MNET_S2S_BID_REQUESTED.auctionId; const bidId = MOCK.MNET_S2S_BID_REQUESTED.bids[0].bidId; - events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, {adUnits: MOCK.AD_UNITS})); + events.emit(AUCTION_INIT, Object.assign({}, MOCK.AUCTION_INIT, { adUnits: MOCK.AD_UNITS })); events.emit(BID_REQUESTED, MOCK.MNET_S2S_BID_REQUESTED); // mark the bid as timed out so bidsReceived contains a non-success entry diff --git a/test/spec/modules/medianetBidAdapter_spec.js b/test/spec/modules/medianetBidAdapter_spec.js index c3c14f3d0bb..15c83e9a265 100644 --- a/test/spec/modules/medianetBidAdapter_spec.js +++ b/test/spec/modules/medianetBidAdapter_spec.js @@ -1,11 +1,11 @@ -import {expect, assert} from 'chai'; -import {spec, EVENTS} from '../../../modules/medianetBidAdapter.js'; -import {POST_ENDPOINT} from '../../../libraries/medianetUtils/constants.js'; +import { expect, assert } from 'chai'; +import { spec, EVENTS } from '../../../modules/medianetBidAdapter.js'; +import { POST_ENDPOINT } from '../../../libraries/medianetUtils/constants.js'; import { makeSlot } from '../integration/faker/googletag.js'; import { config } from '../../../src/config.js'; -import {server} from '../../mocks/xhr.js'; -import {resetWinDimensions} from '../../../src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { server } from '../../mocks/xhr.js'; +import { resetWinDimensions } from '../../../src/utils.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; getGlobal().version = getGlobal().version || 'version'; const VALID_BID_REQUEST = [{ @@ -144,7 +144,7 @@ const VALID_BID_REQUEST_WITH_ORTB2 = [{ 'ortb2Imp': { 'ext': { tid: '277b631f-92f5-4844-8b19-ea13c095d3f1', - 'data': {'pbadslot': '/12345/my-gpt-tag-0'} + 'data': { 'pbadslot': '/12345/my-gpt-tag-0' } } }, 'auctionsCount': 1 @@ -173,7 +173,7 @@ const VALID_BID_REQUEST_WITH_ORTB2 = [{ 'ortb2Imp': { 'ext': { tid: 'c52a5c62-3c2b-4b90-9ff8-ec1487754822', - 'data': {'pbadslot': '/12345/my-gpt-tag-0'} + 'data': { 'pbadslot': '/12345/my-gpt-tag-0' } } }, 'auctionsCount': 1 @@ -1511,7 +1511,7 @@ const SERVER_RESPONSE_PAAPI = { 'callbackURL': 'https://test.com/paapi/v1/abcd' }, 'perBuyerSignals': { - 'https://buyer.test.media.net': [ 'test_buyer_signals' ] + 'https://buyer.test.media.net': ['test_buyer_signals'] }, 'perBuyerTimeouts': { '*': 200 @@ -1571,7 +1571,7 @@ const SERVER_RESPONSE_PAAPI_ORTB = { 'callbackURL': 'https://test.com/paapi/v1/abcd' }, 'perBuyerSignals': { - 'https://buyer.test.media.net': [ 'test_buyer_signals' ] + 'https://buyer.test.media.net': ['test_buyer_signals'] }, 'perBuyerTimeouts': { '*': 200 @@ -2067,12 +2067,12 @@ describe('Media.net bid adapter', function () { }); it('should have valid payload when PAAPI is enabled', function () { - const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); + const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, { ...VALID_AUCTIONDATA, paapi: { enabled: true } }); expect(JSON.parse(bidReq.data)).to.deep.equal(VALID_PAYLOAD_PAAPI); }); it('should send whatever is set in ortb2imp.ext.ae in all bid requests when PAAPI is enabled', function () { - const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); + const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, { ...VALID_AUCTIONDATA, paapi: { enabled: true } }); const data = JSON.parse(bidReq.data); expect(data).to.deep.equal(VALID_PAYLOAD_PAAPI); expect(data.imp[0].ext).to.have.property('ae'); @@ -2190,7 +2190,7 @@ describe('Media.net bid adapter', function () { getBoundingClientRect: () => boundingRect }); - const bidRequest = [{...VALID_BID_REQUEST[0], adUnitCode: code}] + const bidRequest = [{ ...VALID_BID_REQUEST[0], adUnitCode: code }] const bidReq = spec.buildRequests(bidRequest, VALID_AUCTIONDATA); const data = JSON.parse(bidReq.data); expect(data.imp[0].ext.visibility).to.equal(2); @@ -2270,13 +2270,13 @@ describe('Media.net bid adapter', function () { }); it('should have the correlation between paapi[0].bidId and bidreq.imp[0].id', function() { - const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); + const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, { ...VALID_AUCTIONDATA, paapi: { enabled: true } }); const bidRes = spec.interpretResponse(SERVER_RESPONSE_PAAPI, []); expect(bidRes.paapi[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) }); it('should have the correlation between paapi[0].bidId and bidreq.imp[0].id for openRTB response', function() { - const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, {...VALID_AUCTIONDATA, paapi: {enabled: true}}); + const bidReq = spec.buildRequests(VALID_BID_REQUEST_WITH_AE_IN_ORTB2IMP, { ...VALID_AUCTIONDATA, paapi: { enabled: true } }); const bidRes = spec.interpretResponse(SERVER_RESPONSE_PAAPI_ORTB, []); expect(bidRes.paapi[0].bidId).to.equal(JSON.parse(bidReq.data).imp[0].id) }); @@ -2366,7 +2366,7 @@ describe('Media.net bid adapter', function () { }); it('should send bidderError data correctly', function () { const error = { - reason: {message: 'Failed to fetch', status: 500}, + reason: { message: 'Failed to fetch', status: 500 }, timedOut: true, status: 0 } @@ -2380,7 +2380,7 @@ describe('Media.net bid adapter', function () { }]; sandbox.stub(window.navigator, 'sendBeacon').returns(false); - spec.onBidderError({error, bidderRequest: {bids}}); + spec.onBidderError({ error, bidderRequest: { bids } }); const reqBody = new URLSearchParams(server.requests[0].requestBody); assert.equal(server.requests[0].method, 'POST'); diff --git a/test/spec/modules/medianetRtdProvider_spec.js b/test/spec/modules/medianetRtdProvider_spec.js index ffd8109ebf0..90a3c11aa07 100644 --- a/test/spec/modules/medianetRtdProvider_spec.js +++ b/test/spec/modules/medianetRtdProvider_spec.js @@ -51,7 +51,7 @@ describe('medianet realtime module', function () { }); it('auctionInit should pass information to js when loaded', function () { - const auctionObject = {adUnits: []}; + const auctionObject = { adUnits: [] }; medianetRTD.medianetRtdModule.onAuctionInitEvent(auctionObject); const command = window.mnjs.que.pop(); @@ -60,7 +60,7 @@ describe('medianet realtime module', function () { assert.equal(setDataSpy.called, true); assert.equal(setDataSpy.args[0][0].name, 'auctionInit'); - assert.deepEqual(setDataSpy.args[0][0].data, {auction: auctionObject}); + assert.deepEqual(setDataSpy.args[0][0].data, { auction: auctionObject }); }); describe('getTargeting should work correctly', function () { @@ -72,8 +72,8 @@ describe('medianet realtime module', function () { it('should return ad unit codes when ad units are present', function () { const adUnitCodes = ['code1', 'code2']; assert.deepEqual(medianetRTD.medianetRtdModule.getTargetingData(adUnitCodes, {}, {}, {}), { - code1: {'mnadc': 'code1'}, - code2: {'mnadc': 'code2'}, + code1: { 'mnadc': 'code1' }, + code2: { 'mnadc': 'code2' }, }); }); @@ -120,7 +120,7 @@ describe('medianet realtime module', function () { const onCompleteSpy = sandbox.spy(); window.mnjs.onPrebidRequestBid = onPrebidRequestBidSpy = () => { onPrebidRequestBidSpy.called = true; - return {onComplete: onCompleteSpy}; + return { onComplete: onCompleteSpy }; }; medianetRTD.medianetRtdModule.getBidRequestData(requestBidsProps, callbackSpy, conf.dataProviders[0], {}); @@ -136,7 +136,7 @@ describe('medianet realtime module', function () { onCompleteSpy.args[0][0](); assert.equal(callbackSpy.callCount, 1, 'callback should be called when error callback is triggered'); onCompleteSpy.args[0][1]({}, { - 'code1': {ext: {refresh: refreshInformation}} + 'code1': { ext: { refresh: refreshInformation } } }); assert.equal(callbackSpy.callCount, 2, 'callback should be called when success callback is triggered'); assert.isObject(requestBidsProps.adUnits[0].ortb2Imp, 'ORTB object should be set'); diff --git a/test/spec/modules/mediasquareBidAdapter_spec.js b/test/spec/modules/mediasquareBidAdapter_spec.js index caa22f4da1d..3cba1e4bdb7 100644 --- a/test/spec/modules/mediasquareBidAdapter_spec.js +++ b/test/spec/modules/mediasquareBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/mediasquareBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/mediasquareBidAdapter.js'; import { server } from 'test/mocks/xhr.js'; describe('MediaSquare bid adapter tests', function () { @@ -82,37 +82,39 @@ describe('MediaSquare bid adapter tests', function () { sizes: [[300, 250]], getFloor: function (a) { return { currency: 'USD', floor: 1.0 }; }, }]; - var BID_RESPONSE = {'body': { - 'responses': [{ - 'transaction_id': 'cccc1234', - 'cpm': 22.256608, - 'width': 300, - 'height': 250, - 'creative_id': '158534630', - 'currency': 'USD', - 'originalCpm': 25.0123, - 'originalCurrency': 'USD', - 'net_revenue': true, - 'ttl': 300, - 'ad': '< --- creative code --- >', - 'bidder': 'msqClassic', - 'code': 'test/publishername_atf_desktop_rg_pave', - 'bid_id': 'aaaa1234', - 'adomain': ['test.com'], - 'context': 'instream', - 'increment': 1.0, - 'ova': 'cleared', - 'dsa': { - 'behalf': 'some-behalf', - 'paid': 'some-paid', - 'transparency': [{ - 'domain': 'test.com', - 'dsaparams': [1, 2, 3] - }], - 'adrender': 1 - } - }], - }}; + var BID_RESPONSE = { + 'body': { + 'responses': [{ + 'transaction_id': 'cccc1234', + 'cpm': 22.256608, + 'width': 300, + 'height': 250, + 'creative_id': '158534630', + 'currency': 'USD', + 'originalCpm': 25.0123, + 'originalCurrency': 'USD', + 'net_revenue': true, + 'ttl': 300, + 'ad': '< --- creative code --- >', + 'bidder': 'msqClassic', + 'code': 'test/publishername_atf_desktop_rg_pave', + 'bid_id': 'aaaa1234', + 'adomain': ['test.com'], + 'context': 'instream', + 'increment': 1.0, + 'ova': 'cleared', + 'dsa': { + 'behalf': 'some-behalf', + 'paid': 'some-paid', + 'transparency': [{ + 'domain': 'test.com', + 'dsaparams': [1, 2, 3] + }], + 'adrender': 1 + } + }], + } + }; const DEFAULT_OPTIONS = { ortb2: { @@ -260,7 +262,7 @@ describe('MediaSquare bid adapter tests', function () { expect(syncs).to.have.lengthOf(0); }); it('Verifies user sync with cookies in bid response', function () { - BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}]; + BID_RESPONSE.body.cookies = [{ 'type': 'image', 'url': 'http://www.cookie.sync.org/' }]; var syncs = spec.getUserSyncs({}, [BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); expect(syncs).to.have.lengthOf(1); expect(syncs[0]).to.have.property('type').and.to.equal('image'); @@ -278,7 +280,7 @@ describe('MediaSquare bid adapter tests', function () { }); it('Verifies native in bid response', function () { const request = spec.buildRequests(NATIVE_PARAMS, DEFAULT_OPTIONS); - BID_RESPONSE.body.responses[0].native = {'title': 'native title'}; + BID_RESPONSE.body.responses[0].native = { 'title': 'native title' }; const response = spec.interpretResponse(BID_RESPONSE, request); expect(response).to.have.lengthOf(1); const bid = response[0]; @@ -287,7 +289,7 @@ describe('MediaSquare bid adapter tests', function () { }); it('Verifies video in bid response', function () { const request = spec.buildRequests(VIDEO_PARAMS, DEFAULT_OPTIONS); - BID_RESPONSE.body.responses[0].video = {'xml': 'my vast XML', 'url': 'my vast url'}; + BID_RESPONSE.body.responses[0].video = { 'xml': 'my vast XML', 'url': 'my vast url' }; const response = spec.interpretResponse(BID_RESPONSE, request); expect(response).to.have.lengthOf(1); const bid = response[0]; @@ -296,4 +298,25 @@ describe('MediaSquare bid adapter tests', function () { expect(bid).to.have.property('renderer'); delete BID_RESPONSE.body.responses[0].video; }); + it('Verifies burls in bid response', function () { + const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + BID_RESPONSE.body.responses[0].burls = [{ 'url': 'http://myburl.com/track?bid=1.0' }]; + const response = spec.interpretResponse(BID_RESPONSE, request); + expect(response).to.have.lengthOf(1); + const bid = response[0]; + expect(bid.mediasquare).to.have.property('burls'); + expect(bid.mediasquare.burls).to.have.lengthOf(1); + expect(bid.mediasquare.burls[0]).to.have.property('url').and.to.equal('http://myburl.com/track?bid=1.0'); + delete BID_RESPONSE.body.responses[0].burls; + }); + it('Verifies burls bidwon', function () { + const request = spec.buildRequests(DEFAULT_PARAMS, DEFAULT_OPTIONS); + BID_RESPONSE.body.responses[0].burls = [{ 'url': 'http://myburl.com/track?bid=1.0' }]; + const response = spec.interpretResponse(BID_RESPONSE, request); + const won = spec.onBidWon(response[0]); + expect(won).to.equal(true); + expect(server.requests.length).to.equal(1); + expect(server.requests[0].url).to.equal('http://myburl.com/track?bid=1.0'); + delete BID_RESPONSE.body.responses[0].burls; + }); }); diff --git a/test/spec/modules/merkleIdSystem_spec.js b/test/spec/modules/merkleIdSystem_spec.js index 0999cacc8e4..cf307b76117 100644 --- a/test/spec/modules/merkleIdSystem_spec.js +++ b/test/spec/modules/merkleIdSystem_spec.js @@ -1,10 +1,10 @@ import * as ajaxLib from 'src/ajax.js'; import * as utils from 'src/utils.js'; -import {merkleIdSubmodule} from 'modules/merkleIdSystem.js'; +import { merkleIdSubmodule } from 'modules/merkleIdSystem.js'; import sinon from 'sinon'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; const expect = require('chai').expect; @@ -62,10 +62,10 @@ describe('Merkle System', function () { }); it('can decode legacy stored object', function() { - const merkleId = {'pam_id': {'id': 'testmerkleId', 'keyID': 1}}; + const merkleId = { 'pam_id': { 'id': 'testmerkleId', 'keyID': 1 } }; expect(merkleIdSubmodule.decode(merkleId)).to.deep.equal({ - merkleId: {'id': 'testmerkleId', 'keyID': 1} + merkleId: { 'id': 'testmerkleId', 'keyID': 1 } }); }) @@ -159,7 +159,7 @@ describe('Merkle System', function () { storage: STORAGE_PARAMS }; - const submoduleCallback = merkleIdSubmodule.getId(config, {gdpr: {gdprApplies: true}}); + const submoduleCallback = merkleIdSubmodule.getId(config, { gdpr: { gdprApplies: true } }); expect(submoduleCallback).to.be.undefined; expect(utils.logError.args[0][0]).to.exist.and.to.equal('User ID - merkleId submodule does not currently handle consent strings'); }); @@ -208,7 +208,7 @@ describe('Merkle System', function () { }; const yesterday = new Date(Date.now() - 86400000).toUTCString(); - const storedId = {value: 'Merkle_Stored_ID', date: yesterday}; + const storedId = { value: 'Merkle_Stored_ID', date: yesterday }; const id = merkleIdSubmodule.extendId(config, undefined, storedId); @@ -225,7 +225,7 @@ describe('Merkle System', function () { }; const yesterday = new Date(Date.now() - 86400000).toUTCString(); - const storedId = {value: 'Merkle_Stored_ID', date: yesterday}; + const storedId = { value: 'Merkle_Stored_ID', date: yesterday }; const submoduleCallback = merkleIdSubmodule.extendId(config, undefined, storedId).callback; @@ -243,7 +243,7 @@ describe('Merkle System', function () { }; const yesterday = new Date(Date.now() - 86400000).toUTCString(); - const storedId = {value: 'Merkle_Stored_ID', date: yesterday}; + const storedId = { value: 'Merkle_Stored_ID', date: yesterday }; const submoduleCallback = merkleIdSubmodule.extendId(config, undefined, storedId).callback; submoduleCallback(callbackSpy); @@ -293,7 +293,8 @@ describe('Merkle System', function () { expect(newEids.length).to.equal(2); expect(newEids[0]).to.deep.equal({ source: 'ssp1.merkleinc.com', - uids: [{id: 'some-random-id-value', + uids: [{ + id: 'some-random-id-value', atype: 3, ext: { enc: 1, @@ -305,7 +306,8 @@ describe('Merkle System', function () { }); expect(newEids[1]).to.deep.equal({ source: 'ssp2.merkleinc.com', - uids: [{id: 'another-random-id-value', + uids: [{ + id: 'another-random-id-value', atype: 3, ext: { third: 4, diff --git a/test/spec/modules/mgidBidAdapter_spec.js b/test/spec/modules/mgidBidAdapter_spec.js index 3019cebe377..88c3c56ba03 100644 --- a/test/spec/modules/mgidBidAdapter_spec.js +++ b/test/spec/modules/mgidBidAdapter_spec.js @@ -1,10 +1,10 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec, storage } from 'modules/mgidBidAdapter.js'; import { version } from 'package.json'; import * as utils from '../../../src/utils.js'; import { getDNT } from 'libraries/dnt/index.js'; -import {USERSYNC_DEFAULT_CONFIG} from '../../../src/userSync.js'; -import {config} from '../../../src/config.js'; +import { USERSYNC_DEFAULT_CONFIG } from '../../../src/userSync.js'; +import { config } from '../../../src/config.js'; describe('Mgid bid adapter', function () { let sandbox; @@ -62,7 +62,7 @@ describe('Mgid bid adapter', function () { it('should return false when valid params are not passed', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '', placementId: ''}; + bid.params = { accountId: '', placementId: '' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); @@ -75,7 +75,7 @@ describe('Mgid bid adapter', function () { sizes: [[300, 250]] } }; - bid.params = {accountId: 2, placementId: 1}; + bid.params = { accountId: 2, placementId: 1 }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); @@ -88,7 +88,7 @@ describe('Mgid bid adapter', function () { sizes: [[300, 250]] } }; - bid.params = {accountId: 2, placementId: 1}; + bid.params = { accountId: 2, placementId: 1 }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); @@ -101,7 +101,7 @@ describe('Mgid bid adapter', function () { sizes: [[300, 250]] } }; - bid.params = {accountId: 2, placementId: 1}; + bid.params = { accountId: 2, placementId: 1 }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); @@ -113,21 +113,21 @@ describe('Mgid bid adapter', function () { sizes: [[300, 250]] } }; - bid.params = {accountId: '0', placementId: '00'}; + bid.params = { accountId: '0', placementId: '00' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should return false when valid mediaTypes are not passed', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should return false when valid mediaTypes.banner are not passed', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { }; expect(spec.isBidRequestValid(bid)).to.equal(false); @@ -136,7 +136,7 @@ describe('Mgid bid adapter', function () { it('should return false when valid mediaTypes.banner.sizes are not passed', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { sizes: [] }; @@ -146,7 +146,7 @@ describe('Mgid bid adapter', function () { it('should return false when valid mediaTypes.banner.sizes are not valid', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { sizes: [300, 250] }; @@ -157,7 +157,7 @@ describe('Mgid bid adapter', function () { const bid = Object.assign({}, sbid); delete bid.params; bid.adUnitCode = 'div'; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { banner: { sizes: [[300, 250]] @@ -168,7 +168,7 @@ describe('Mgid bid adapter', function () { it('should return false when valid mediaTypes.native is not object', function () { const bid = Object.assign({}, sbid); - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { native: [] }; @@ -178,7 +178,7 @@ describe('Mgid bid adapter', function () { it('should return false when mediaTypes.native is empty object', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { native: {} }; @@ -188,7 +188,7 @@ describe('Mgid bid adapter', function () { it('should return false when mediaTypes.native is invalid object', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {accountId: '1', placementId: '1'}; + bid.params = { accountId: '1', placementId: '1' }; bid.mediaTypes = { native: { image: { @@ -201,19 +201,19 @@ describe('Mgid bid adapter', function () { it('should return false when mediaTypes.native has unsupported required asset', function () { const bid = Object.assign({}, sbid); - bid.params = {accountId: '2', placementId: '1'}; + bid.params = { accountId: '2', placementId: '1' }; bid.mediaTypes = { native: { - title: {required: true}, - image: {required: false, sizes: [80, 80]}, - sponsored: {required: false}, + title: { required: true }, + image: { required: false, sizes: [80, 80] }, + sponsored: { required: false }, }, }; bid.nativeParams = { - title: {required: true}, - image: {required: false, sizes: [80, 80]}, - sponsored: {required: false}, - unsupported: {required: true}, + title: { required: true }, + image: { required: false, sizes: [80, 80] }, + sponsored: { required: false }, + unsupported: { required: true }, }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); @@ -221,18 +221,18 @@ describe('Mgid bid adapter', function () { it('should return true when mediaTypes.native all assets needed', function () { const bid = Object.assign({}, sbid); bid.adUnitCode = 'div'; - bid.params = {accountId: '2', placementId: '1'}; + bid.params = { accountId: '2', placementId: '1' }; bid.mediaTypes = { native: { - title: {required: true}, - image: {required: false, sizes: [80, 80]}, - sponsored: {required: false}, + title: { required: true }, + image: { required: false, sizes: [80, 80] }, + sponsored: { required: false }, }, }; bid.nativeParams = { - title: {required: true}, - image: {required: false, sizes: [80, 80]}, - sponsored: {required: false}, + title: { required: true }, + image: { required: false, sizes: [80, 80] }, + sponsored: { required: false }, }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); @@ -334,7 +334,7 @@ describe('Mgid bid adapter', function () { }, }; afterEach(function () { - config.setConfig({coppa: undefined}) + config.setConfig({ coppa: undefined }) }) it('should return undefined if no validBidRequests passed', function () { @@ -357,7 +357,7 @@ describe('Mgid bid adapter', function () { getDataFromLocalStorageStub.restore(); }); it('should proper handle gdpr', function () { - config.setConfig({coppa: 1}) + config.setConfig({ coppa: 1 }) const bid = Object.assign({}, abid); bid.mediaTypes = { banner: { @@ -365,12 +365,12 @@ describe('Mgid bid adapter', function () { } }; const bidRequests = [bid]; - const request = spec.buildRequests(bidRequests, {gdprConsent: {consentString: 'gdpr', gdprApplies: true}, uspConsent: 'usp', gppConsent: {gppString: 'gpp'}}); + const request = spec.buildRequests(bidRequests, { gdprConsent: { consentString: 'gdpr', gdprApplies: true }, uspConsent: 'usp', gppConsent: { gppString: 'gpp' } }); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); expect(request.method).deep.equal('POST'); const data = JSON.parse(request.data); - expect(data.user).deep.equal({ext: {consent: 'gdpr'}}); - expect(data.regs).deep.equal({ext: {gdpr: 1, us_privacy: 'usp'}, gpp: 'gpp', coppa: 1}); + expect(data.user).deep.equal({ ext: { consent: 'gdpr' } }); + expect(data.regs).deep.equal({ ext: { gdpr: 1, us_privacy: 'usp' }, gpp: 'gpp', coppa: 1 }); }); it('should handle refererInfo', function () { const bid = Object.assign({}, abid); @@ -383,7 +383,7 @@ describe('Mgid bid adapter', function () { const domain = 'site.com' const page = `http://${domain}/site.html` const ref = 'http://ref.com/ref.html' - const request = spec.buildRequests(bidRequests, {refererInfo: {page, ref}}); + const request = spec.buildRequests(bidRequests, { refererInfo: { page, ref } }); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); expect(request.method).deep.equal('POST'); const data = JSON.parse(request.data); @@ -405,7 +405,7 @@ describe('Mgid bid adapter', function () { const bidRequests = [bid]; const request = spec.buildRequests(bidRequests); const data = JSON.parse(request.data); - expect(data.source).to.deep.equal({ext: {schain: bid.ortb2.source.ext.schain}}); + expect(data.source).to.deep.equal({ ext: { schain: bid.ortb2.source.ext.schain } }); }); it('should handle userId', function () { const bid = Object.assign({}, abid); @@ -415,7 +415,7 @@ describe('Mgid bid adapter', function () { } }; const bidRequests = [bid]; - const bidderRequest = {userId: 'userid'}; + const bidderRequest = { userId: 'userid' }; const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.url).deep.equal('https://prebid.mgid.com/prebid/1'); expect(request.method).deep.equal('POST'); @@ -459,7 +459,7 @@ describe('Mgid bid adapter', function () { expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid'); - expect(data.imp[0].banner).to.deep.equal({w: 300, h: 250}); + expect(data.imp[0].banner).to.deep.equal({ w: 300, h: 250 }); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', @@ -473,8 +473,8 @@ describe('Mgid bid adapter', function () { native: '', }; bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, + title: { required: true }, + image: { sizes: [80, 80] }, }; const bidRequests = [bid]; const request = spec.buildRequests(bidRequests); @@ -486,8 +486,8 @@ describe('Mgid bid adapter', function () { native: '', }; bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, + title: { required: true }, + image: { sizes: [80, 80] }, sponsored: { }, }; @@ -509,7 +509,7 @@ describe('Mgid bid adapter', function () { expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); expect(data.imp[0].ext.gpid).to.deep.equal('/1111/gpid'); - expect(data.imp[0].native).is.a('object').and.to.deep.equal({'request': {'assets': [{'id': 1, 'required': 1, 'title': {'len': 80}}, {'id': 2, 'img': {'h': 80, 'type': 3, 'w': 80}, 'required': 0}, {'data': {'type': 1}, 'id': 11, 'required': 0}], 'plcmtcnt': 1}}); + expect(data.imp[0].native).is.a('object').and.to.deep.equal({ 'request': { 'assets': [{ 'id': 1, 'required': 1, 'title': { 'len': 80 } }, { 'id': 2, 'img': { 'h': 80, 'type': 3, 'w': 80 }, 'required': 0 }, { 'data': { 'type': 1 }, 'id': 11, 'required': 0 }], 'plcmtcnt': 1 } }); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', @@ -523,8 +523,8 @@ describe('Mgid bid adapter', function () { native: '', }; bid.nativeParams = { - title: {required: true}, - image: {wmin: 50, hmin: 50, required: true}, + title: { required: true }, + image: { wmin: 50, hmin: 50, required: true }, icon: {}, sponsored: { }, }; @@ -546,7 +546,7 @@ describe('Mgid bid adapter', function () { expect(data.device.w).equal(screenWidth); expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); - expect(data.imp[0].native).is.a('object').and.to.deep.equal({'request': {'assets': [{'id': 1, 'required': 1, 'title': {'len': 80}}, {'id': 2, 'img': {'h': 328, hmin: 50, 'type': 3, 'w': 492, wmin: 50}, 'required': 1}, {'id': 3, 'img': {'h': 50, 'type': 1, 'w': 50}, 'required': 0}, {'data': {'type': 1}, 'id': 11, 'required': 0}], 'plcmtcnt': 1}}); + expect(data.imp[0].native).is.a('object').and.to.deep.equal({ 'request': { 'assets': [{ 'id': 1, 'required': 1, 'title': { 'len': 80 } }, { 'id': 2, 'img': { 'h': 328, hmin: 50, 'type': 3, 'w': 492, wmin: 50 }, 'required': 1 }, { 'id': 3, 'img': { 'h': 50, 'type': 1, 'w': 50 }, 'required': 0 }, { 'data': { 'type': 1 }, 'id': 11, 'required': 0 }], 'plcmtcnt': 1 } }); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', @@ -560,8 +560,8 @@ describe('Mgid bid adapter', function () { native: '', }; bid.nativeParams = { - title: {required: true}, - image: {sizes: [80, 80]}, + title: { required: true }, + image: { sizes: [80, 80] }, sponsoredBy: { }, }; @@ -582,7 +582,7 @@ describe('Mgid bid adapter', function () { expect(data.device.w).equal(screenWidth); expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); - expect(data.imp[0].native).is.a('object').and.to.deep.equal({'request': {'assets': [{'id': 1, 'required': 1, 'title': {'len': 80}}, {'id': 2, 'img': {'h': 80, 'type': 3, 'w': 80}, 'required': 0}, {'data': {'type': 1}, 'id': 4, 'required': 0}], 'plcmtcnt': 1}}); + expect(data.imp[0].native).is.a('object').and.to.deep.equal({ 'request': { 'assets': [{ 'id': 1, 'required': 1, 'title': { 'len': 80 } }, { 'id': 2, 'img': { 'h': 80, 'type': 3, 'w': 80 }, 'required': 0 }, { 'data': { 'type': 1 }, 'id': 4, 'required': 0 }], 'plcmtcnt': 1 } }); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ 'method': 'POST', @@ -615,7 +615,7 @@ describe('Mgid bid adapter', function () { expect(data.device.w).equal(screenWidth); expect(data.device.language).to.deep.equal(lang); expect(data.imp[0].tagid).to.deep.equal('2/div'); - expect(data.imp[0].banner).to.deep.equal({w: 300, h: 600, format: [{w: 300, h: 600}, {w: 300, h: 250}], pos: 1}); + expect(data.imp[0].banner).to.deep.equal({ w: 300, h: 600, format: [{ w: 300, h: 600 }, { w: 300, h: 250 }], pos: 1 }); expect(data.imp[0].secure).to.deep.equal(secure); expect(request).to.deep.equal({ @@ -650,8 +650,8 @@ describe('Mgid bid adapter', function () { segtax: 1, }, segment: [ - {id: '123'}, - {id: '456'}, + { id: '123' }, + { id: '456' }, ], }] } @@ -666,8 +666,8 @@ describe('Mgid bid adapter', function () { segtax: 2, }, segment: [ - {'id': '789'}, - {'id': '987'}, + { 'id': '789' }, + { 'id': '987' }, ], }] }, @@ -696,21 +696,21 @@ describe('Mgid bid adapter', function () { describe('interpretResponse', function () { it('should not push proper native bid response if adm is missing', function () { const resp = { - body: {'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{'bid': [{'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': {'place': 0, 'crtype': 'native'}, 'adomain': ['test.com']}], 'seat': '44082'}]} + body: { 'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{ 'bid': [{ 'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': { 'place': 0, 'crtype': 'native' }, 'adomain': ['test.com'] }], 'seat': '44082' }] } }; const bids = spec.interpretResponse(resp); expect(bids).to.deep.equal([]) }); it('should not push proper native bid response if assets is empty', function () { const resp = { - body: {'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{'bid': [{'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': {'place': 0, 'crtype': 'native'}, 'adomain': ['test.com']}], 'seat': '44082'}]} + body: { 'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{ 'bid': [{ 'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': { 'place': 0, 'crtype': 'native' }, 'adomain': ['test.com'] }], 'seat': '44082' }] } }; const bids = spec.interpretResponse(resp); expect(bids).to.deep.equal([]) }); it('should push proper native bid response, assets1', function () { const resp = { - body: {'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{'bid': [{'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[{"id":1,"required":0,"title":{"text":"title1"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"image_src"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"icon_src"}},{"id":4,"required":0,"data":{"type":4,"value":"sponsored"}},{"id":5,"required":0,"data":{"type":6,"value":"price1"}},{"id":6,"required":0,"data":{"type":7,"value":"price2"}}],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': {'place': 0, 'crtype': 'native'}, 'adomain': ['test.com']}], 'seat': '44082'}], ext: {'muidn': 'userid'}} + body: { 'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{ 'bid': [{ 'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[{"id":1,"required":0,"title":{"text":"title1"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"image_src"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"icon_src"}},{"id":4,"required":0,"data":{"type":4,"value":"sponsored"}},{"id":5,"required":0,"data":{"type":6,"value":"price1"}},{"id":6,"required":0,"data":{"type":7,"value":"price2"}}],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': { 'place': 0, 'crtype': 'native' }, 'adomain': ['test.com'] }], 'seat': '44082' }], ext: { 'muidn': 'userid' } } }; const bids = spec.interpretResponse(resp); expect(bids).to.deep.equal([{ @@ -723,7 +723,7 @@ describe('Mgid bid adapter', function () { 'height': 0, 'isBurl': true, 'mediaType': 'native', - 'meta': {'advertiserDomains': ['test.com']}, + 'meta': { 'advertiserDomains': ['test.com'] }, 'native': { 'clickTrackers': [], 'clickUrl': 'link_url', @@ -754,7 +754,7 @@ describe('Mgid bid adapter', function () { }); it('should push proper native bid response, assets2', function () { const resp = { - body: {'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{'bid': [{'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[{"id":1,"required":0,"title":{"text":"title1"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"image_src"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"icon_src"}}],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': {'place': 0, 'crtype': 'native'}, 'adomain': ['test.com']}], 'seat': '44082'}]} + body: { 'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': 'GBP', 'seatbid': [{ 'bid': [{ 'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': '{"native":{"ver":"1.1","link":{"url":"link_url"},"assets":[{"id":1,"required":0,"title":{"text":"title1"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"image_src"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"icon_src"}}],"imptrackers":["imptrackers1"]}}', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'ext': { 'place': 0, 'crtype': 'native' }, 'adomain': ['test.com'] }], 'seat': '44082' }] } }; const bids = spec.interpretResponse(resp); expect(bids).to.deep.equal([ @@ -767,7 +767,7 @@ describe('Mgid bid adapter', function () { 'height': 0, 'isBurl': true, 'mediaType': 'native', - 'meta': {'advertiserDomains': ['test.com']}, + 'meta': { 'advertiserDomains': ['test.com'] }, 'netRevenue': true, 'nurl': 'https nurl', 'burl': 'https burl', @@ -801,7 +801,7 @@ describe('Mgid bid adapter', function () { }); it('should push proper banner bid response', function () { const resp = { - body: {'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': '', 'seatbid': [{'bid': [{'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': 'html: adm', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'adomain': ['test.com']}], 'seat': '44082'}]} + body: { 'id': '57c0c2b1b732ca', 'bidid': '57c0c2b1b732ca', 'cur': '', 'seatbid': [{ 'bid': [{ 'price': 1.5, 'h': 600, 'w': 300, 'id': '1', 'impid': '61e40632c53fc2', 'adid': '2898532/2419121/2592854/2499195', 'nurl': 'https nurl', 'burl': 'https burl', 'adm': 'html: adm', 'cid': '44082', 'crid': '2898532/2419121/2592854/2499195', 'cat': ['IAB7', 'IAB14', 'IAB18-3', 'IAB1-2'], 'adomain': ['test.com'] }], 'seat': '44082' }] } }; const bids = spec.interpretResponse(resp); expect(bids).to.deep.equal([ @@ -814,7 +814,7 @@ describe('Mgid bid adapter', function () { 'height': 600, 'isBurl': true, 'mediaType': 'banner', - 'meta': {'advertiserDomains': ['test.com']}, + 'meta': { 'advertiserDomains': ['test.com'] }, 'netRevenue': true, 'nurl': 'https nurl', 'burl': 'https burl', @@ -828,32 +828,32 @@ describe('Mgid bid adapter', function () { describe('getUserSyncs', function () { afterEach(function() { - config.setConfig({userSync: {syncsPerBidder: USERSYNC_DEFAULT_CONFIG.syncsPerBidder}}); + config.setConfig({ userSync: { syncsPerBidder: USERSYNC_DEFAULT_CONFIG.syncsPerBidder } }); }); it('should do nothing on getUserSyncs without inputs', function () { expect(spec.getUserSyncs()).to.equal(undefined) }); it('should return frame object with empty consents', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}) + const sync = spec.getUserSyncs({ iframeEnabled: true }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=&gdpr=0/) }); it('should return frame object with gdpr consent', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}, undefined, {consentString: 'consent', gdprApplies: true}) + const sync = spec.getUserSyncs({ iframeEnabled: true }, undefined, { consentString: 'consent', gdprApplies: true }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent&gdpr=1/) }); it('should return frame object with gdpr + usp', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const sync = spec.getUserSyncs({ iframeEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) }); it('should return img object with gdpr + usp', function () { - config.setConfig({userSync: {syncsPerBidder: undefined}}); - const sync = spec.getUserSyncs({pixelEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + config.setConfig({ userSync: { syncsPerBidder: undefined } }); + const sync = spec.getUserSyncs({ pixelEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(USERSYNC_DEFAULT_CONFIG.syncsPerBidder) for (let i = 0; i < USERSYNC_DEFAULT_CONFIG.syncsPerBidder; i++) { expect(sync[i]).to.have.property('type', 'image') @@ -861,14 +861,14 @@ describe('Mgid bid adapter', function () { } }); it('should return frame object with gdpr + usp', function () { - const sync = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const sync = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) }); it('should return img (pixels) objects with gdpr + usp', function () { - const response = [{body: {ext: {cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif']}}}] - const sync = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, response, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const response = [{ body: { ext: { cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif'] } } }] + const sync = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, response, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(2) expect(sync[0]).to.have.property('type', 'image') expect(sync[0]).to.have.property('url').match(/http:\/\/cm\.mgid\.com\/i\.gif\?cdsp=1111&cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) @@ -879,12 +879,12 @@ describe('Mgid bid adapter', function () { describe('getUserSyncs with img from ext.cm and gdpr + usp + coppa + gpp', function () { afterEach(function() { - config.setConfig({coppa: undefined}) + config.setConfig({ coppa: undefined }) }); it('should return img (pixels) objects with gdpr + usp + coppa + gpp', function () { - config.setConfig({coppa: 1}); - const response = [{body: {ext: {cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif']}}}] - const sync = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, response, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}, {gppString: 'gpp'}) + config.setConfig({ coppa: 1 }); + const response = [{ body: { ext: { cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif'] } } }] + const sync = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, response, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }, { gppString: 'gpp' }) expect(sync).to.have.length(2) expect(sync[0]).to.have.property('type', 'image') expect(sync[0]).to.have.property('url').match(/http:\/\/cm\.mgid\.com\/i\.gif\?cdsp=1111&cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2&gppString=gpp&coppa=1/) @@ -903,7 +903,7 @@ describe('Mgid bid adapter', function () { it('should replace nurl and burl for native', function () { const burl = 'burl&s=${' + 'AUCTION_PRICE}'; const nurl = 'nurl&s=${' + 'AUCTION_PRICE}'; - const bid = {'bidderCode': 'mgid', 'width': 0, 'height': 0, 'statusMessage': 'Bid available', 'adId': '3d0b6ff1dda89', 'requestId': '2a423489e058a1', 'mediaType': 'native', 'source': 'client', 'ad': '{"native":{"ver":"1.1","link":{"url":"LinkURL"},"assets":[{"id":1,"required":0,"title":{"text":"TITLE"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"ImageURL"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"IconURL"}},{"id":11,"required":0,"data":{"type":1,"value":"sponsored"}}],"imptrackers":["ImpTrackerURL"]}}', 'cpm': 0.66, 'creativeId': '353538_591471', 'currency': 'USD', 'dealId': '', 'netRevenue': true, 'ttl': 300, 'nurl': nurl, 'burl': burl, 'isBurl': true, 'native': {'title': 'TITLE', 'image': {'url': 'ImageURL', 'height': 80, 'width': 80}, 'icon': {'url': 'IconURL', 'height': 50, 'width': 50}, 'sponsored': 'sponsored', 'clickUrl': 'LinkURL', 'clickTrackers': [], 'impressionTrackers': ['ImpTrackerURL'], 'jstracker': []}, 'auctionId': 'a92bffce-14d2-4f8f-a78a-7b9b5e4d28fa', 'responseTimestamp': 1556867386065, 'requestTimestamp': 1556867385916, 'bidder': 'mgid', 'adUnitCode': 'div-gpt-ad-1555415275793-0', 'timeToRespond': 149, 'pbLg': '0.50', 'pbMg': '0.60', 'pbHg': '0.66', 'pbAg': '0.65', 'pbDg': '0.66', 'pbCg': '', 'size': '0x0', 'adserverTargeting': {'hb_bidder': 'mgid', 'hb_adid': '3d0b6ff1dda89', 'hb_pb': '0.66', 'hb_size': '0x0', 'hb_source': 'client', 'hb_format': 'native', 'hb_native_title': 'TITLE', 'hb_native_image': 'hb_native_image:3d0b6ff1dda89', 'hb_native_icon': 'IconURL', 'hb_native_linkurl': 'hb_native_linkurl:3d0b6ff1dda89'}, 'status': 'targetingSet', 'params': [{'accountId': '184', 'placementId': '353538'}]}; + const bid = { 'bidderCode': 'mgid', 'width': 0, 'height': 0, 'statusMessage': 'Bid available', 'adId': '3d0b6ff1dda89', 'requestId': '2a423489e058a1', 'mediaType': 'native', 'source': 'client', 'ad': '{"native":{"ver":"1.1","link":{"url":"LinkURL"},"assets":[{"id":1,"required":0,"title":{"text":"TITLE"}},{"id":2,"required":0,"img":{"w":80,"h":80,"type":3,"url":"ImageURL"}},{"id":3,"required":0,"img":{"w":50,"h":50,"type":1,"url":"IconURL"}},{"id":11,"required":0,"data":{"type":1,"value":"sponsored"}}],"imptrackers":["ImpTrackerURL"]}}', 'cpm': 0.66, 'creativeId': '353538_591471', 'currency': 'USD', 'dealId': '', 'netRevenue': true, 'ttl': 300, 'nurl': nurl, 'burl': burl, 'isBurl': true, 'native': { 'title': 'TITLE', 'image': { 'url': 'ImageURL', 'height': 80, 'width': 80 }, 'icon': { 'url': 'IconURL', 'height': 50, 'width': 50 }, 'sponsored': 'sponsored', 'clickUrl': 'LinkURL', 'clickTrackers': [], 'impressionTrackers': ['ImpTrackerURL'], 'jstracker': [] }, 'auctionId': 'a92bffce-14d2-4f8f-a78a-7b9b5e4d28fa', 'responseTimestamp': 1556867386065, 'requestTimestamp': 1556867385916, 'bidder': 'mgid', 'adUnitCode': 'div-gpt-ad-1555415275793-0', 'timeToRespond': 149, 'pbLg': '0.50', 'pbMg': '0.60', 'pbHg': '0.66', 'pbAg': '0.65', 'pbDg': '0.66', 'pbCg': '', 'size': '0x0', 'adserverTargeting': { 'hb_bidder': 'mgid', 'hb_adid': '3d0b6ff1dda89', 'hb_pb': '0.66', 'hb_size': '0x0', 'hb_source': 'client', 'hb_format': 'native', 'hb_native_title': 'TITLE', 'hb_native_image': 'hb_native_image:3d0b6ff1dda89', 'hb_native_icon': 'IconURL', 'hb_native_linkurl': 'hb_native_linkurl:3d0b6ff1dda89' }, 'status': 'targetingSet', 'params': [{ 'accountId': '184', 'placementId': '353538' }] }; spec.onBidWon(bid); expect(bid.nurl).to.deep.equal('nurl&s=0.66'); expect(bid.burl).to.deep.equal('burl&s=0.66'); @@ -911,7 +911,7 @@ describe('Mgid bid adapter', function () { it('should replace nurl and burl for banner', function () { const burl = 'burl&s=${' + 'AUCTION_PRICE}'; const nurl = 'nurl&s=${' + 'AUCTION_PRICE}'; - const bid = {'bidderCode': 'mgid', 'width': 0, 'height': 0, 'statusMessage': 'Bid available', 'adId': '3d0b6ff1dda89', 'requestId': '2a423489e058a1', 'mediaType': 'banner', 'source': 'client', 'ad': burl, 'cpm': 0.66, 'creativeId': '353538_591471', 'currency': 'USD', 'dealId': '', 'netRevenue': true, 'ttl': 300, 'nurl': nurl, 'burl': burl, 'isBurl': true, 'auctionId': 'a92bffce-14d2-4f8f-a78a-7b9b5e4d28fa', 'responseTimestamp': 1556867386065, 'requestTimestamp': 1556867385916, 'bidder': 'mgid', 'adUnitCode': 'div-gpt-ad-1555415275793-0', 'timeToRespond': 149, 'pbLg': '0.50', 'pbMg': '0.60', 'pbHg': '0.66', 'pbAg': '0.65', 'pbDg': '0.66', 'pbCg': '', 'size': '0x0', 'adserverTargeting': {'hb_bidder': 'mgid', 'hb_adid': '3d0b6ff1dda89', 'hb_pb': '0.66', 'hb_size': '0x0', 'hb_source': 'client', 'hb_format': 'banner', 'hb_banner_title': 'TITLE', 'hb_banner_image': 'hb_banner_image:3d0b6ff1dda89', 'hb_banner_icon': 'IconURL', 'hb_banner_linkurl': 'hb_banner_linkurl:3d0b6ff1dda89'}, 'status': 'targetingSet', 'params': [{'accountId': '184', 'placementId': '353538'}]}; + const bid = { 'bidderCode': 'mgid', 'width': 0, 'height': 0, 'statusMessage': 'Bid available', 'adId': '3d0b6ff1dda89', 'requestId': '2a423489e058a1', 'mediaType': 'banner', 'source': 'client', 'ad': burl, 'cpm': 0.66, 'creativeId': '353538_591471', 'currency': 'USD', 'dealId': '', 'netRevenue': true, 'ttl': 300, 'nurl': nurl, 'burl': burl, 'isBurl': true, 'auctionId': 'a92bffce-14d2-4f8f-a78a-7b9b5e4d28fa', 'responseTimestamp': 1556867386065, 'requestTimestamp': 1556867385916, 'bidder': 'mgid', 'adUnitCode': 'div-gpt-ad-1555415275793-0', 'timeToRespond': 149, 'pbLg': '0.50', 'pbMg': '0.60', 'pbHg': '0.66', 'pbAg': '0.65', 'pbDg': '0.66', 'pbCg': '', 'size': '0x0', 'adserverTargeting': { 'hb_bidder': 'mgid', 'hb_adid': '3d0b6ff1dda89', 'hb_pb': '0.66', 'hb_size': '0x0', 'hb_source': 'client', 'hb_format': 'banner', 'hb_banner_title': 'TITLE', 'hb_banner_image': 'hb_banner_image:3d0b6ff1dda89', 'hb_banner_icon': 'IconURL', 'hb_banner_linkurl': 'hb_banner_linkurl:3d0b6ff1dda89' }, 'status': 'targetingSet', 'params': [{ 'accountId': '184', 'placementId': '353538' }] }; spec.onBidWon(bid); expect(bid.nurl).to.deep.equal('nurl&s=0.66'); expect(bid.burl).to.deep.equal(burl); diff --git a/test/spec/modules/mgidRtdProvider_spec.js b/test/spec/modules/mgidRtdProvider_spec.js index 7fd41a3c4c5..4aa0d65f1bc 100644 --- a/test/spec/modules/mgidRtdProvider_spec.js +++ b/test/spec/modules/mgidRtdProvider_spec.js @@ -1,7 +1,7 @@ import { mgidSubmodule, storage } from '../../../modules/mgidRtdProvider.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; import * as refererDetection from '../../../src/refererDetection.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; describe('Mgid RTD submodule', () => { let clock; @@ -26,14 +26,14 @@ describe('Mgid RTD submodule', () => { }); it('init is successfull, when clientSiteId is defined', () => { - expect(mgidSubmodule.init({params: {clientSiteId: 123}})).to.be.true; + expect(mgidSubmodule.init({ params: { clientSiteId: 123 } })).to.be.true; }); it('init is unsuccessfull, when clientSiteId is not defined', () => { expect(mgidSubmodule.init({})).to.be.false; }); - it('getBidRequestData send all params to our endpoint and succesfully modifies ortb2', () => { + it('getBidRequestData send all params to our endpoint and successfully modifies ortb2', () => { const responseObj = { userSegments: ['100', '200'], userSegtax: 5, @@ -59,7 +59,7 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, { gdpr: { gdprApplies: true, @@ -71,7 +71,7 @@ describe('Mgid RTD submodule', () => { server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify(responseObj) ); @@ -134,13 +134,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify({}) ); @@ -168,7 +168,7 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, { gdpr: { gdprApplies: false, @@ -180,7 +180,7 @@ describe('Mgid RTD submodule', () => { server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify({}) ); @@ -213,13 +213,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify({}) ); @@ -246,13 +246,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, JSON.stringify({}) ); @@ -273,13 +273,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 200, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, '{' ); @@ -299,13 +299,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 204, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, ); assert.deepEqual(reqBidsConfigObj.ortb2Fragments.global, {}); @@ -324,13 +324,13 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123}}, + { params: { clientSiteId: 123 } }, {} ); server.requests[0].respond( 500, - {'Content-Type': 'application/json'}, + { 'Content-Type': 'application/json' }, '{}' ); @@ -350,7 +350,7 @@ describe('Mgid RTD submodule', () => { mgidSubmodule.getBidRequestData( reqBidsConfigObj, onDone, - {params: {clientSiteId: 123, timeout: 500}}, + { params: { clientSiteId: 123, timeout: 500 } }, {} ); diff --git a/test/spec/modules/mgidXBidAdapter_spec.js b/test/spec/modules/mgidXBidAdapter_spec.js index f6e1fd68082..86d448e5be8 100644 --- a/test/spec/modules/mgidXBidAdapter_spec.js +++ b/test/spec/modules/mgidXBidAdapter_spec.js @@ -492,32 +492,32 @@ describe('MGIDXBidAdapter', function () { describe('getUserSyncs', function () { afterEach(function() { - config.setConfig({userSync: {syncsPerBidder: USERSYNC_DEFAULT_CONFIG.syncsPerBidder}}); + config.setConfig({ userSync: { syncsPerBidder: USERSYNC_DEFAULT_CONFIG.syncsPerBidder } }); }); it('should do nothing on getUserSyncs without inputs', function () { expect(spec.getUserSyncs()).to.equal(undefined) }); it('should return frame object with empty consents', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}) + const sync = spec.getUserSyncs({ iframeEnabled: true }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=&gdpr=0/) }); it('should return frame object with gdpr consent', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}, undefined, {consentString: 'consent', gdprApplies: true}) + const sync = spec.getUserSyncs({ iframeEnabled: true }, undefined, { consentString: 'consent', gdprApplies: true }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent&gdpr=1/) }); it('should return frame object with gdpr + usp', function () { - const sync = spec.getUserSyncs({iframeEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const sync = spec.getUserSyncs({ iframeEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) }); it('should return img object with gdpr + usp', function () { - config.setConfig({userSync: {syncsPerBidder: undefined}}); - const sync = spec.getUserSyncs({pixelEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + config.setConfig({ userSync: { syncsPerBidder: undefined } }); + const sync = spec.getUserSyncs({ pixelEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(USERSYNC_DEFAULT_CONFIG.syncsPerBidder) for (let i = 0; i < USERSYNC_DEFAULT_CONFIG.syncsPerBidder; i++) { expect(sync[i]).to.have.property('type', 'image') @@ -525,14 +525,14 @@ describe('MGIDXBidAdapter', function () { } }); it('should return frame object with gdpr + usp', function () { - const sync = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, undefined, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const sync = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, undefined, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(1) expect(sync[0]).to.have.property('type', 'iframe') expect(sync[0]).to.have.property('url').match(/https:\/\/cm\.mgid\.com\/i\.html\?cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) }); it('should return img (pixels) objects with gdpr + usp', function () { - const response = [{body: {ext: {cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif']}}}] - const sync = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, response, {consentString: 'consent1', gdprApplies: true}, {'consentString': 'consent2'}) + const response = [{ body: { ext: { cm: ['http://cm.mgid.com/i.gif?cdsp=1111', 'http://cm.mgid.com/i.gif'] } } }] + const sync = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, response, { consentString: 'consent1', gdprApplies: true }, { 'consentString': 'consent2' }) expect(sync).to.have.length(2) expect(sync[0]).to.have.property('type', 'image') expect(sync[0]).to.have.property('url').match(/http:\/\/cm\.mgid\.com\/i\.gif\?cdsp=1111&cbuster=\d+&gdpr_consent=consent1&gdpr=1&us_privacy=consent2/) diff --git a/test/spec/modules/microadBidAdapter_spec.js b/test/spec/modules/microadBidAdapter_spec.js index f1a4fbec9e7..013d6d3f0f1 100644 --- a/test/spec/modules/microadBidAdapter_spec.js +++ b/test/spec/modules/microadBidAdapter_spec.js @@ -286,36 +286,36 @@ describe('microadBidAdapter', () => { Object.entries({ 'IM-UID': { - userId: {imuid: 'imuid-sample'}, - expected: {aids: JSON.stringify([{type: 6, id: 'imuid-sample'}])} + userId: { imuid: 'imuid-sample' }, + expected: { aids: JSON.stringify([{ type: 6, id: 'imuid-sample' }]) } }, 'ID5 ID': { - userId: {id5id: {uid: 'id5id-sample'}}, - expected: {aids: JSON.stringify([{type: 8, id: 'id5id-sample'}])} + userId: { id5id: { uid: 'id5id-sample' } }, + expected: { aids: JSON.stringify([{ type: 8, id: 'id5id-sample' }]) } }, 'Unified ID': { - userId: {tdid: 'unified-sample'}, - expected: {aids: JSON.stringify([{type: 9, id: 'unified-sample'}])} + userId: { tdid: 'unified-sample' }, + expected: { aids: JSON.stringify([{ type: 9, id: 'unified-sample' }]) } }, 'Novatiq Snowflake ID': { - userId: {novatiq: {snowflake: 'novatiq-sample'}}, - expected: {aids: JSON.stringify([{type: 10, id: 'novatiq-sample'}])} + userId: { novatiq: { snowflake: 'novatiq-sample' } }, + expected: { aids: JSON.stringify([{ type: 10, id: 'novatiq-sample' }]) } }, 'AudienceOne User ID': { - userId: {dacId: {id: 'audience-one-sample'}}, - expected: {aids: JSON.stringify([{type: 12, id: 'audience-one-sample'}])} + userId: { dacId: { id: 'audience-one-sample' } }, + expected: { aids: JSON.stringify([{ type: 12, id: 'audience-one-sample' }]) } }, 'Ramp ID and Liveramp identity': { - userId: {idl_env: 'idl-env-sample'}, - expected: {idl_env: 'idl-env-sample', aids: JSON.stringify([{type: 13, id: 'idl-env-sample'}])} + userId: { idl_env: 'idl-env-sample' }, + expected: { idl_env: 'idl-env-sample', aids: JSON.stringify([{ type: 13, id: 'idl-env-sample' }]) } }, 'Criteo ID': { - userId: {criteoId: 'criteo-id-sample'}, - expected: {aids: JSON.stringify([{type: 14, id: 'criteo-id-sample'}])} + userId: { criteoId: 'criteo-id-sample' }, + expected: { aids: JSON.stringify([{ type: 14, id: 'criteo-id-sample' }]) } }, 'Shared ID': { - userId: {pubcid: 'shared-id-sample'}, - expected: {aids: JSON.stringify([{type: 15, id: 'shared-id-sample'}])} + userId: { pubcid: 'shared-id-sample' }, + expected: { aids: JSON.stringify([{ type: 15, id: 'shared-id-sample' }]) } } }).forEach(([test, arg]) => { it(`should add ${test} if it is available in request parameters`, () => { @@ -333,32 +333,32 @@ describe('microadBidAdapter', () => { Object.entries({ 'ID5 ID': { - userId: {id5id: {uid: 'id5id-sample'}}, + userId: { id5id: { uid: 'id5id-sample' } }, userIdAsEids: [ { source: 'id5-sync.com', - uids: [{id: 'id5id-sample', aType: 1, ext: {linkType: 2, abTestingControlGroup: false}}] + uids: [{ id: 'id5id-sample', aType: 1, ext: { linkType: 2, abTestingControlGroup: false } }] } ], expected: { - aids: JSON.stringify([{type: 8, id: 'id5id-sample', ext: {linkType: 2, abTestingControlGroup: false}}]) + aids: JSON.stringify([{ type: 8, id: 'id5id-sample', ext: { linkType: 2, abTestingControlGroup: false } }]) } }, 'Unified ID': { - userId: {tdid: 'unified-sample'}, + userId: { tdid: 'unified-sample' }, userIdAsEids: [ { source: 'adserver.org', - uids: [{id: 'unified-sample', aType: 1, ext: {rtiPartner: 'TDID'}}] + uids: [{ id: 'unified-sample', aType: 1, ext: { rtiPartner: 'TDID' } }] } ], - expected: {aids: JSON.stringify([{type: 9, id: 'unified-sample', ext: {rtiPartner: 'TDID'}}])} + expected: { aids: JSON.stringify([{ type: 9, id: 'unified-sample', ext: { rtiPartner: 'TDID' } }]) } }, 'not add': { - userId: {id5id: {uid: 'id5id-sample'}}, + userId: { id5id: { uid: 'id5id-sample' } }, userIdAsEids: [], expected: { - aids: JSON.stringify([{type: 8, id: 'id5id-sample'}]) + aids: JSON.stringify([{ type: 8, id: 'id5id-sample' }]) } } }).forEach(([test, arg]) => { @@ -665,12 +665,12 @@ describe('microadBidAdapter', () => { } }; const expectedIframeSyncs = [ - {type: 'iframe', url: 'https://www.example.com/iframe1'}, - {type: 'iframe', url: 'https://www.example.com/iframe2'} + { type: 'iframe', url: 'https://www.example.com/iframe1' }, + { type: 'iframe', url: 'https://www.example.com/iframe2' } ]; const expectedImageSyncs = [ - {type: 'image', url: 'https://www.example.com/image1'}, - {type: 'image', url: 'https://www.example.com/image2'} + { type: 'image', url: 'https://www.example.com/image1' }, + { type: 'image', url: 'https://www.example.com/image2' } ]; it('should return nothing if no sync urls are set', () => { diff --git a/test/spec/modules/mileBidAdapter_spec.js b/test/spec/modules/mileBidAdapter_spec.js new file mode 100644 index 00000000000..34171f86114 --- /dev/null +++ b/test/spec/modules/mileBidAdapter_spec.js @@ -0,0 +1,691 @@ +import { expect } from 'chai'; +import { spec, siteIdTracker, publisherIdTracker } from 'modules/mileBidAdapter.js'; +import { BANNER } from 'src/mediaTypes.js'; +import * as ajax from 'src/ajax.js'; +import * as utils from 'src/utils.js'; + +describe('mileBidAdapter', function () { + describe('isBidRequestValid', function () { + let bid; + + beforeEach(function () { + bid = { + bidder: 'mile', + params: { + placementId: '12345', + siteId: 'site123', + publisherId: 'pub456' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }; + }); + + it('should return true when all required params are present', function () { + expect(spec.isBidRequestValid(bid)).to.be.true; + }); + + it('should return false when placementId is missing', function () { + delete bid.params.placementId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when siteId is missing', function () { + delete bid.params.siteId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when publisherId is missing', function () { + delete bid.params.publisherId; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when params is missing', function () { + delete bid.params; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + + it('should return false when params is null', function () { + bid.params = null; + expect(spec.isBidRequestValid(bid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let validBidRequests, bidderRequest; + + beforeEach(function () { + validBidRequests = [{ + bidder: 'mile', + params: { + placementId: '12345', + siteId: 'site123', + publisherId: 'pub456' + }, + mediaTypes: { + banner: { + sizes: [[300, 250], [728, 90]] + } + }, + adUnitCode: 'test-ad-unit', + bidId: 'bid123', + ortb2Imp: { + ext: { + gpid: '/test/ad/unit' + } + } + }]; + + bidderRequest = { + bidderCode: 'mile', + bidderRequestId: 'bidderReq123', + auctionId: 'auction123', + timeout: 3000, + refererInfo: { + page: 'https://example.com/page', + domain: 'example.com', + ref: 'https://google.com' + }, + ortb2: { + source: { + tid: 'transaction123' + } + } + }; + }); + + it('should return a valid server request object', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request).to.be.an('object'); + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://pbs.atmtd.com/mile/v1/request'); + expect(request.data).to.be.an('object'); + }); + + it('should build OpenRTB 2.5 compliant request', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = request.data; + + expect(data.id).to.equal('bidderReq123'); + expect(data.imp).to.be.an('array').with.lengthOf(1); + expect(data.tmax).to.equal(3000); + expect(data.cur).to.deep.equal(['USD']); + expect(data.site).to.be.an('object'); + expect(data.device).to.be.an('object'); + expect(data.source).to.be.an('object'); + }); + + it('should include imp object with correct structure', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const imp = request.data.imp[0]; + + expect(imp.id).to.equal('bid123'); + expect(imp.tagid).to.equal('12345'); + expect(imp.secure).to.equal(1); + expect(imp.banner).to.be.an('object'); + expect(imp.banner.format).to.be.an('array').with.lengthOf(2); + expect(imp.banner.format[0]).to.deep.equal({ w: 300, h: 250 }); + expect(imp.banner.format[1]).to.deep.equal({ w: 728, h: 90 }); + }); + + it('should include ext fields in imp object', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const imp = request.data.imp[0]; + + expect(imp.ext.adUnitCode).to.equal('test-ad-unit'); + expect(imp.ext.placementId).to.equal('12345'); + expect(imp.ext.gpid).to.equal('/test/ad/unit'); + }); + + it('should include site object with publisher info', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const site = request.data.site; + + expect(site.id).to.equal('site123'); + expect(site.page).to.equal('https://example.com/page'); + expect(site.domain).to.equal('example.com'); + expect(site.ref).to.equal('https://google.com'); + expect(site.publisher.id).to.equal('pub456'); + }); + + it('should include device object', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const device = request.data.device; + + expect(device.ua).to.be.a('string'); + expect(device.language).to.be.a('string'); + expect(device.dnt).to.be.a('number'); + }); + + it('should include source object with tid', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const source = request.data.source; + + expect(source.tid).to.equal('transaction123'); + }); + + it('should include bidfloor when floor price is available', function () { + validBidRequests[0].getFloor = function() { + return { floor: 0.5, currency: 'USD' }; + }; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + const imp = request.data.imp[0]; + + expect(imp.bidfloor).to.equal(0.5); + expect(imp.bidfloorcur).to.equal('USD'); + }); + + it('should include GDPR consent when present', function () { + bidderRequest.gdprConsent = { + gdprApplies: true, + consentString: 'consent-string-123' + }; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request.data.regs.ext.gdpr).to.equal(1); + expect(request.data.user.ext.consent).to.equal('consent-string-123'); + }); + + it('should include US Privacy consent when present', function () { + bidderRequest.uspConsent = '1YNN'; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request.data.regs.ext.us_privacy).to.equal('1YNN'); + }); + + it('should include GPP consent when present', function () { + bidderRequest.gppConsent = { + gppString: 'gpp-string-123', + applicableSections: [1, 2, 3] + }; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request.data.regs.gpp).to.equal('gpp-string-123'); + expect(request.data.regs.gpp_sid).to.deep.equal([1, 2, 3]); + }); + + it('should include user EIDs when present', function () { + validBidRequests[0].userIdAsEids = [ + { + source: 'pubcid.org', + uids: [{ id: 'user-id-123' }] + } + ]; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request.data.user.ext.eids).to.be.an('array').with.lengthOf(1); + expect(request.data.user.ext.eids[0].source).to.equal('pubcid.org'); + }); + + it('should include supply chain when present', function () { + validBidRequests[0].ortb2 = { + source: { + ext: { + schain: { + ver: '1.0', + complete: 1, + nodes: [] + } + } + } + }; + + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request.data.source.ext.schain).to.be.an('object'); + expect(request.data.source.ext.schain.ver).to.equal('1.0'); + }); + + it('should handle multiple bid requests with same siteId and publisherId', function () { + const secondBid = { + ...validBidRequests[0], + bidId: 'bid456', + params: { + placementId: '67890', + siteId: 'site123', + publisherId: 'pub456' + } + }; + + const request = spec.buildRequests([validBidRequests[0], secondBid], bidderRequest); + + expect(request.data.imp).to.be.an('array').with.lengthOf(2); + expect(request.data.imp[0].id).to.equal('bid123'); + expect(request.data.imp[1].id).to.equal('bid456'); + }); + + it('should reject bids with different siteId', function () { + const firstBid = { + bidder: 'mile', + params: { + placementId: '12345', + siteId: 'site123', + publisherId: 'pub456' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }; + + const secondBid = { + bidder: 'mile', + params: { + placementId: '67890', + siteId: 'differentSite', // Different siteId + publisherId: 'pub456' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }; + + // First bid should be valid + expect(spec.isBidRequestValid(firstBid)).to.be.true; + + // Second bid should be rejected due to siteId mismatch + expect(spec.isBidRequestValid(secondBid)).to.be.false; + }); + + it('should reject bids with different publisherId', function () { + const firstBid = { + bidder: 'mile', + params: { + placementId: '12345', + siteId: 'site123', + publisherId: 'pub456' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }; + + const secondBid = { + bidder: 'mile', + params: { + placementId: '67890', + siteId: 'site123', + publisherId: 'differentPub' + }, + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }; + + // First bid should be valid + expect(spec.isBidRequestValid(firstBid)).to.be.true; + + // Second bid should be rejected due to publisherId mismatch + expect(spec.isBidRequestValid(secondBid)).to.be.false; + }); + }); + + describe('interpretResponse', function () { + let serverResponse; + + beforeEach(function () { + serverResponse = { + body: { + site: { + id: 'site123', + domain: 'example.com', + publisher: { + id: 'pub456' + }, + page: 'https://example.com/page', + }, + cur: 'USD', + bids: [ + { + requestId: 'bid123', + cpm: 1.5, + width: 300, + height: 250, + ad: '
test ad
', + creativeId: 'creative123', + ttl: 300, + nurl: 'https://example.com/win?price=${AUCTION_PRICE}', + adomain: ['advertiser.com'], + upstreamBidder: 'upstreamBidder' + } + ] + } + }; + }); + + it('should return an array of bid responses', function () { + const bids = spec.interpretResponse(serverResponse); + + expect(bids).to.be.an('array').with.lengthOf(1); + }); + + it('should parse bid response correctly', function () { + const bids = spec.interpretResponse(serverResponse); + const bid = bids[0]; + + expect(bid.requestId).to.equal('bid123'); + expect(bid.cpm).to.equal(1.5); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.ad).to.equal('
test ad
'); + expect(bid.creativeId).to.equal('creative123'); + expect(bid.currency).to.equal('USD'); + expect(bid.ttl).to.equal(300); + expect(bid.netRevenue).to.be.true; + expect(bid.mediaType).to.equal(BANNER); + expect(bid.meta.upstreamBidder).to.equal('upstreamBidder'); + expect(bid.meta.siteUID).to.equal('site123'); + expect(bid.meta.publisherID).to.equal('pub456'); + expect(bid.meta.page).to.equal('https://example.com/page'); + expect(bid.meta.domain).to.equal('example.com'); + }); + + it('should include nurl in bid response', function () { + const bids = spec.interpretResponse(serverResponse); + const bid = bids[0]; + + expect(bid.nurl).to.equal('https://example.com/win?price=${AUCTION_PRICE}'); + }); + + it('should include meta.advertiserDomains', function () { + const bids = spec.interpretResponse(serverResponse); + const bid = bids[0]; + + expect(bid.meta.advertiserDomains).to.deep.equal(['advertiser.com']); + }); + + it('should handle empty response', function () { + const bids = spec.interpretResponse({ body: null }); + + expect(bids).to.be.an('array').with.lengthOf(0); + }); + + it('should handle response with no bids', function () { + serverResponse.body.bids = []; + const bids = spec.interpretResponse(serverResponse); + + expect(bids).to.be.an('array').with.lengthOf(0); + }); + + it('should handle alternative field names (w/h instead of width/height)', function () { + serverResponse.body.bids[0] = { + requestId: 'bid123', + cpm: 1.5, + w: 728, + h: 90, + ad: '
test ad
' + }; + + const bids = spec.interpretResponse(serverResponse); + const bid = bids[0]; + + expect(bid.width).to.equal(728); + expect(bid.height).to.equal(90); + }); + + it('should use default currency if not specified', function () { + delete serverResponse.body.cur; + const bids = spec.interpretResponse(serverResponse); + + expect(bids[0].currency).to.equal('USD'); + }); + + it('should handle response with no site or publisher', function () { + delete serverResponse.body.site; + delete serverResponse.body.publisher; + const bids = spec.interpretResponse(serverResponse); + + expect(bids[0].meta.siteUID).to.be.empty; + expect(bids[0].meta.publisherID).to.be.empty; + expect(bids[0].meta.page).to.be.empty; + expect(bids[0].meta.domain).to.be.empty; + }); + }); + + describe('getUserSyncs', function () { + let syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent; + + beforeEach(function () { + syncOptions = { + iframeEnabled: true, + pixelEnabled: true + }; + serverResponses = []; + }); + + it('should return iframe sync when enabled', function () { + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + + expect(syncs).to.be.an('array').with.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.include('https://scripts.atmtd.com/user-sync/load-cookie.html'); + }); + + it('should not return syncs when iframe is disabled', function () { + syncOptions.iframeEnabled = false; + const syncs = spec.getUserSyncs(syncOptions, serverResponses); + + expect(syncs).to.be.an('array').with.lengthOf(0); + }); + + it('should include GDPR consent params', function () { + gdprConsent = { + gdprApplies: true, + consentString: 'consent-string-123' + }; + + const syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent); + + expect(syncs[0].url).to.include('gdpr=1'); + expect(syncs[0].url).to.include('gdpr_consent=consent-string-123'); + }); + + it('should include US Privacy consent param', function () { + uspConsent = '1YNN'; + + const syncs = spec.getUserSyncs(syncOptions, serverResponses, null, uspConsent); + + expect(syncs[0].url).to.include('us_privacy=1YNN'); + }); + + it('should include GPP consent params', function () { + gppConsent = { + gppString: 'gpp-string-123', + applicableSections: [1, 2, 3] + }; + + const syncs = spec.getUserSyncs(syncOptions, serverResponses, null, null, gppConsent); + + expect(syncs[0].url).to.include('gpp=gpp-string-123'); + expect(syncs[0].url).to.include('gpp_sid=1%2C2%2C3'); + }); + + it('should include all consent params when present', function () { + gdprConsent = { gdprApplies: true, consentString: 'gdpr-consent' }; + uspConsent = '1YNN'; + gppConsent = { gppString: 'gpp-string', applicableSections: [1] }; + + const syncs = spec.getUserSyncs(syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('gdpr=1'); + expect(syncs[0].url).to.include('us_privacy=1YNN'); + expect(syncs[0].url).to.include('gpp=gpp-string'); + }); + }); + + describe('onBidWon', function () { + let bid, ajaxStub; + + beforeEach(function () { + bid = { + bidder: 'mile', + adUnitCode: 'test-ad-unit', + requestId: 'bid123', + cpm: 1.5, + width: 300, + height: 250, + nurl: 'https://example.com/win', + meta: { + upstreamBidder: 'upstreamBidder', + siteUID: 'mRUDIL', + publisherID: 'pub456', + page: 'https://example.com/page', + domain: 'example.com' + } + }; + + ajaxStub = sinon.stub(ajax, 'ajax'); + }); + + afterEach(function () { + ajaxStub.restore(); + }); + + it('should call ajax with win notification endpoint', function () { + spec.onBidWon(bid); + + expect(ajaxStub.calledTwice).to.be.true; + + // First call to notification endpoint + const firstCall = ajaxStub.getCall(0); + expect(firstCall.args[0]).to.equal('https://e01.atmtd.com/bidanalytics-event/json'); + + // Second call to nurl + const secondCall = ajaxStub.getCall(1); + expect(secondCall.args[0]).to.equal('https://example.com/win'); + }); + + it('should send correct win notification data', function () { + spec.onBidWon(bid); + + const firstCall = ajaxStub.getCall(0); + const notificationData = JSON.parse(firstCall.args[2])[0]; + + expect(notificationData.adUnitCode).to.equal('test-ad-unit'); + expect(notificationData.metaData.impressionID[0]).to.equal('bid123'); + expect(notificationData.winningBidder).to.equal('upstreamBidder'); + expect(notificationData.cpm).to.equal(1.5); + expect(notificationData.winningSize).to.equal('300x250'); + expect(notificationData.eventType).to.equal('mile-bidder-win-notify'); + expect(notificationData.timestamp).to.be.a('number'); + expect(notificationData.siteUID).to.equal('mRUDIL'); + expect(notificationData.yetiPublisherID).to.equal('pub456'); + expect(notificationData.page).to.equal('https://example.com/page'); + expect(notificationData.site).to.equal('example.com'); + }); + + it('should call nurl with GET request', function () { + spec.onBidWon(bid); + + const secondCall = ajaxStub.getCall(1); + const options = secondCall.args[3]; + + expect(options.method).to.equal('GET'); + }); + }); + + describe('onTimeout', function () { + let timeoutData, ajaxStub; + + beforeEach(function () { + timeoutData = [ + { + bidder: 'mile', + bidId: 'bid123', + adUnitCode: 'test-ad-unit-1', + timeout: 3000, + params: { + placementId: '12345', + siteId: 'site123', + publisherId: 'pub456' + } + }, + { + bidder: 'mile', + bidId: 'bid456', + adUnitCode: 'test-ad-unit-2', + timeout: 3000, + params: { + placementId: '67890', + siteId: 'site123', + publisherId: 'pub456' + } + } + ]; + + ajaxStub = sinon.stub(ajax, 'ajax'); + }); + + afterEach(function () { + ajaxStub.restore(); + }); + + it('should call ajax for each timed out bid', function () { + spec.onTimeout(timeoutData); + + expect(ajaxStub.callCount).to.equal(1); + }); + + it('should send correct timeout notification data', function () { + spec.onTimeout(timeoutData); + + const firstCall = ajaxStub.getCall(0); + expect(firstCall.args[0]).to.equal('https://e01.atmtd.com/bidanalytics-event/json'); + + const notificationData = JSON.parse(firstCall.args[2])[0]; + expect(notificationData.adUnitCode).to.equal('test-ad-unit-1'); + expect(notificationData.metaData.impressionID[0]).to.equal('bid123'); + expect(notificationData.metaData.configuredTimeout[0]).to.equal('3000'); + expect(notificationData.eventType).to.equal('mile-bidder-timeout'); + expect(notificationData.timestamp).to.be.a('number'); + }); + + it('should handle single timeout', function () { + spec.onTimeout([timeoutData[0]]); + + expect(ajaxStub.calledOnce).to.be.true; + }); + + it('should handle empty timeout array', function () { + spec.onTimeout([]); + + expect(ajaxStub.called).to.be.false; + }); + }); + + describe('adapter specification', function () { + it('should have correct bidder code', function () { + expect(spec.code).to.equal('mile'); + }); + + it('should support BANNER media type', function () { + expect(spec.supportedMediaTypes).to.be.an('array'); + expect(spec.supportedMediaTypes).to.include(BANNER); + }); + + it('should have required adapter functions', function () { + expect(spec.isBidRequestValid).to.be.a('function'); + expect(spec.buildRequests).to.be.a('function'); + expect(spec.interpretResponse).to.be.a('function'); + expect(spec.getUserSyncs).to.be.a('function'); + expect(spec.onBidWon).to.be.a('function'); + expect(spec.onTimeout).to.be.a('function'); + }); + }); +}); diff --git a/test/spec/modules/minutemediaBidAdapter_spec.js b/test/spec/modules/minutemediaBidAdapter_spec.js index c8f41a42781..4bbbe6476b4 100644 --- a/test/spec/modules/minutemediaBidAdapter_spec.js +++ b/test/spec/modules/minutemediaBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/minutemediaBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; import * as utils from 'src/utils.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; const ENDPOINT = 'https://hb.minutemedia-prebid.com/hb-mm-multi'; const TEST_ENDPOINT = 'https://hb.minutemedia-prebid.com/hb-multi-mm-test'; @@ -95,7 +95,7 @@ describe('minutemediaAdapter', function () { 'mediaTypes': { 'banner': { 'sizes': [ - [ 300, 250 ] + [300, 250] ] }, 'video': { @@ -324,7 +324,7 @@ describe('minutemediaAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -337,7 +337,7 @@ describe('minutemediaAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -345,7 +345,7 @@ describe('minutemediaAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); @@ -353,7 +353,7 @@ describe('minutemediaAdapter', function () { }); it('should not send the gpp param if gppConsent is false in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: false}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: false }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gpp'); @@ -361,7 +361,7 @@ describe('minutemediaAdapter', function () { }); it('should send the gpp param if gppConsent is true in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: {gppString: 'test-consent-string', applicableSections: [7]}}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: { gppString: 'test-consent-string', applicableSections: [7] } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gpp', 'test-consent-string'); @@ -422,15 +422,15 @@ describe('minutemediaAdapter', function () { 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -444,20 +444,20 @@ describe('minutemediaAdapter', function () { 'sua': { 'platform': { 'brand': 'macOS', - 'version': [ '12', '4', '0' ] + 'version': ['12', '4', '0'] }, 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, diff --git a/test/spec/modules/missenaBidAdapter_spec.js b/test/spec/modules/missenaBidAdapter_spec.js index f4e09a981fe..67e64e264d2 100644 --- a/test/spec/modules/missenaBidAdapter_spec.js +++ b/test/spec/modules/missenaBidAdapter_spec.js @@ -4,7 +4,7 @@ import { BANNER } from '../../../src/mediaTypes.js'; import { config } from 'src/config.js'; import * as autoplay from 'libraries/autoplayDetection/autoplay.js'; import { getWinDimensions } from '../../../src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const REFERRER = 'https://referer'; const REFERRER2 = 'https://referer2'; @@ -367,5 +367,69 @@ describe('Missena Adapter', function () { expect(userSync[0].type).to.be.equal('iframe'); expect(userSync[0].url).to.be.equal(expectedUrl); }); + + it('sync frame url should contain gpp data when present', function () { + const gppConsent = { + gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', + applicableSections: [7, 8], + }; + const userSync = spec.getUserSyncs( + iframeEnabledOptions, + [], + {}, + undefined, + gppConsent, + ); + expect(userSync.length).to.be.equal(1); + expect(userSync[0].type).to.be.equal('iframe'); + const syncUrl = new URL(userSync[0].url); + expect(syncUrl.searchParams.get('gpp')).to.equal(gppConsent.gppString); + expect(syncUrl.searchParams.get('gpp_sid')).to.equal('7,8'); + }); + + it('sync frame url should not contain gpp data when gppConsent is undefined', function () { + const userSync = spec.getUserSyncs( + iframeEnabledOptions, + [], + {}, + undefined, + undefined, + ); + expect(userSync.length).to.be.equal(1); + expect(userSync[0].url).to.not.contain('gpp'); + }); + + it('sync frame url should not contain gpp data when gppString is empty', function () { + const userSync = spec.getUserSyncs( + iframeEnabledOptions, + [], + {}, + undefined, + { gppString: '', applicableSections: [7] }, + ); + expect(userSync.length).to.be.equal(1); + expect(userSync[0].url).to.not.contain('gpp'); + }); + + it('sync frame url should contain all consent params together', function () { + const gppConsent = { + gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', + applicableSections: [7], + }; + const userSync = spec.getUserSyncs( + iframeEnabledOptions, + [], + { gdprApplies: true, consentString }, + '1YNN', + gppConsent, + ); + expect(userSync.length).to.be.equal(1); + const syncUrl = new URL(userSync[0].url); + expect(syncUrl.searchParams.get('gdpr')).to.equal('1'); + expect(syncUrl.searchParams.get('gdpr_consent')).to.equal(consentString); + expect(syncUrl.searchParams.get('us_privacy')).to.equal('1YNN'); + expect(syncUrl.searchParams.get('gpp')).to.equal(gppConsent.gppString); + expect(syncUrl.searchParams.get('gpp_sid')).to.equal('7'); + }); }); }); diff --git a/test/spec/modules/mobilefuseBidAdapter_spec.js b/test/spec/modules/mobilefuseBidAdapter_spec.js index b234dbc404d..e6ccce07052 100644 --- a/test/spec/modules/mobilefuseBidAdapter_spec.js +++ b/test/spec/modules/mobilefuseBidAdapter_spec.js @@ -60,7 +60,7 @@ const serverResponse = { describe('mobilefuseBidAdapter', function () { it('should validate bids', function () { expect(spec.isBidRequestValid(bidRequest)).to.be.true; - expect(spec.isBidRequestValid({params: {}})).to.be.false; + expect(spec.isBidRequestValid({ params: {} })).to.be.false; }); it('should build a valid request payload', function () { @@ -139,7 +139,7 @@ describe('mobilefuseBidAdapter', function () { it('should return user syncs with proper query params when iframe sync is enabled', function () { const syncs = spec.getUserSyncs( - {iframeEnabled: true}, + { iframeEnabled: true }, [], null, bidderRequest.uspConsent, @@ -168,7 +168,7 @@ describe('mobilefuseBidAdapter', function () { }; const syncs = spec.getUserSyncs( - {iframeEnabled: false}, + { iframeEnabled: false }, [response], null, bidderRequest.uspConsent, diff --git a/test/spec/modules/mobkoiAnalyticsAdapter_spec.js b/test/spec/modules/mobkoiAnalyticsAdapter_spec.js index a3b785f4405..9b42b5ca3bb 100644 --- a/test/spec/modules/mobkoiAnalyticsAdapter_spec.js +++ b/test/spec/modules/mobkoiAnalyticsAdapter_spec.js @@ -71,7 +71,7 @@ const getBidderResponse = () => ({ const getMockEvents = () => { const sizes = [800, 300]; const timestamp = Date.now(); - const auctionOrBidError = {timestamp, error: 'error', bidderRequest: { bidderRequestId: requestId }} + const auctionOrBidError = { timestamp, error: 'error', bidderRequest: { bidderRequestId: requestId } } return { AUCTION_TIMEOUT: auctionOrBidError, @@ -452,7 +452,7 @@ describe('mobkoiAnalyticsAdapter', function () { it('should throw an error if the object type could not be determined', function () { expect(() => { - utils.determineObjType({dumbAttribute: 'bid'}) + utils.determineObjType({ dumbAttribute: 'bid' }) }).to.throw(); }); @@ -482,7 +482,7 @@ describe('mobkoiAnalyticsAdapter', function () { }) it('should throw an error if custom fields are provided and one of them is not a string', () => { - const customFields = {impid: 'bid-123', bidId: 123} + const customFields = { impid: 'bid-123', bidId: 123 } expect(() => { utils.mergePayloadAndCustomFields({}, customFields) }).to.throw(); diff --git a/test/spec/modules/multibid_spec.js b/test/spec/modules/multibid_spec.js index c48e1d65263..5bd06b6d751 100644 --- a/test/spec/modules/multibid_spec.js +++ b/test/spec/modules/multibid_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { addBidResponseHook, adjustBidderRequestsHook, @@ -8,8 +8,8 @@ import { targetBidPoolHook, validateMultibid } from 'modules/multibid/index.js'; -import {config} from 'src/config.js'; -import {getHighestCpm} from '../../../src/utils/reducers.js'; +import { config } from 'src/config.js'; +import { getHighestCpm } from '../../../src/utils/reducers.js'; describe('multibid adapter', function () { const bidArray = [{ @@ -73,8 +73,8 @@ describe('multibid adapter', function () { 'bidderRequestId': '10e78266423c0e', 'bids': [{ 'bidder': 'bidderA', - 'params': {'placementId': 1234567}, - 'crumbs': {'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412'}, + 'params': { 'placementId': 1234567 }, + 'crumbs': { 'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412' }, 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] @@ -97,8 +97,8 @@ describe('multibid adapter', function () { 'bidderRequestId': '10e78266423c0e', 'bids': [{ 'bidder': 'bidderB', - 'params': {'placementId': 1234567}, - 'crumbs': {'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412'}, + 'params': { 'placementId': 1234567 }, + 'crumbs': { 'pubcid': 'fb4cfc66-ff3d-4fda-bef8-3f2cb6fe9412' }, 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] @@ -134,7 +134,7 @@ describe('multibid adapter', function () { }); it('does not modify bidderRequest when no multibid config exists', function () { - const bidRequests = [{...bidderRequests[0]}]; + const bidRequests = [{ ...bidderRequests[0] }]; adjustBidderRequestsHook(callbackFn, bidRequests); @@ -143,11 +143,11 @@ describe('multibid adapter', function () { }); it('does modify bidderRequest when multibid config exists', function () { - const bidRequests = [{...bidderRequests[0]}]; + const bidRequests = [{ ...bidderRequests[0] }]; - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2 }] }); - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}]); + adjustBidderRequestsHook(callbackFn, [{ ...bidderRequests[0] }]); expect(result).to.not.equal(null); expect(result).to.not.deep.equal(bidRequests); @@ -155,11 +155,11 @@ describe('multibid adapter', function () { }); it('does modify bidderRequest when multibid config exists using bidders array', function () { - const bidRequests = [{...bidderRequests[0]}]; + const bidRequests = [{ ...bidderRequests[0] }]; - config.setConfig({multibid: [{bidders: ['bidderA'], maxBids: 2}]}); + config.setConfig({ multibid: [{ bidders: ['bidderA'], maxBids: 2 }] }); - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}]); + adjustBidderRequestsHook(callbackFn, [{ ...bidderRequests[0] }]); expect(result).to.not.equal(null); expect(result).to.not.deep.equal(bidRequests); @@ -167,11 +167,11 @@ describe('multibid adapter', function () { }); it('does only modifies bidderRequest when multibid config exists for bidder', function () { - const bidRequests = [{...bidderRequests[0]}, {...bidderRequests[1]}]; + const bidRequests = [{ ...bidderRequests[0] }, { ...bidderRequests[1] }]; - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2 }] }); - adjustBidderRequestsHook(callbackFn, [{...bidderRequests[0]}, {...bidderRequests[1]}]); + adjustBidderRequestsHook(callbackFn, [{ ...bidderRequests[0] }, { ...bidderRequests[1] }]); expect(result).to.not.equal(null); expect(result[0]).to.not.deep.equal(bidRequests[0]); @@ -196,9 +196,9 @@ describe('multibid adapter', function () { it('adds original bids and does not modify', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); expect(result).to.not.equal(null); expect(result.adUnitCode).to.not.equal(null); @@ -208,7 +208,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); expect(result).to.not.equal(null); expect(result.adUnitCode).to.not.equal(null); @@ -219,11 +219,11 @@ describe('multibid adapter', function () { it('modifies and adds both bids based on multibid configuration', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -236,7 +236,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); bids[1].multibidPrefix = 'bidA'; bids[1].originalBidder = 'bidderA'; @@ -255,7 +255,7 @@ describe('multibid adapter', function () { it('only modifies bids defined in the multibid configuration', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; bids.push({ 'bidderCode': 'bidderB', @@ -265,9 +265,9 @@ describe('multibid adapter', function () { 'bidder': 'bidderB', }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -280,7 +280,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); bids[1].multibidPrefix = 'bidA'; bids[1].originalBidder = 'bidderA'; @@ -296,7 +296,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[2] }); expect(result).to.not.equal(null); expect(result.adUnitCode).to.not.equal(null); @@ -307,7 +307,7 @@ describe('multibid adapter', function () { it('only modifies and returns bids under limit for a specific bidder in the multibid configuration', function () { const adUnitCode = 'test.div'; - let bids = [{...bidArray[0]}, {...bidArray[1]}]; + let bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; bids.push({ 'bidderCode': 'bidderA', @@ -317,9 +317,9 @@ describe('multibid adapter', function () { 'bidder': 'bidderA', }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -332,7 +332,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); bids[1].multibidPrefix = 'bidA'; bids[1].originalBidder = 'bidderA'; @@ -348,14 +348,14 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[2] }); expect(result).to.equal(null); }); it('if no prefix in multibid configuration, modifies and returns bids under limit without preifx property', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; bids.push({ 'bidderCode': 'bidderA', @@ -365,9 +365,9 @@ describe('multibid adapter', function () { 'bidder': 'bidderA', }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2 }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].originalBidder = 'bidderA'; @@ -379,7 +379,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); bids[1].originalBidder = 'bidderA'; bids[1].originalRequestId = '2e6j8s05r4363h'; @@ -393,14 +393,14 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[2] }); expect(result).to.equal(null); }); it('does not include extra bids if cpm is less than floor value', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArrayAlt[1]}, {...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}]; + const bids = [{ ...bidArrayAlt[1] }, { ...bidArrayAlt[0] }, { ...bidArrayAlt[2] }, { ...bidArrayAlt[3] }]; bids.map(bid => { bid.floorData = { @@ -424,9 +424,9 @@ describe('multibid adapter', function () { return bid; }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -440,13 +440,13 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[1]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[1] }); expect(result).to.equal(null); result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[2]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[2] }); expect(result).to.not.equal(null); expect(result.adUnitCode).to.not.equal(null); @@ -457,7 +457,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[3]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[3] }); expect(result).to.not.equal(null); expect(result.adUnitCode).to.not.equal(null); @@ -469,7 +469,7 @@ describe('multibid adapter', function () { it('does include extra bids if cpm is not less than floor value', function () { const adUnitCode = 'test.div'; - const bids = [{...bidArrayAlt[1]}, {...bidArrayAlt[0]}]; + const bids = [{ ...bidArrayAlt[1] }, { ...bidArrayAlt[0] }]; bids.map(bid => { bid.floorData = { @@ -493,9 +493,9 @@ describe('multibid adapter', function () { return bid; }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -509,7 +509,7 @@ describe('multibid adapter', function () { result = null; - addBidResponseHook(callbackFn, adUnitCode, {...bids[0]}); + addBidResponseHook(callbackFn, adUnitCode, { ...bids[0] }); bids[0].multibidPrefix = 'bidA'; bids[0].originalBidder = 'bidderA'; @@ -543,7 +543,7 @@ describe('multibid adapter', function () { }); it('it does not run filter on bidsReceived if no multibid configuration found', function () { - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; targetBidPoolHook(callbackFn, bids, getHighestCpm); expect(result).to.not.equal(null); @@ -557,9 +557,9 @@ describe('multibid adapter', function () { }); it('it does filter on bidsReceived if multibid configuration found with no prefix', function () { - const bids = [{...bidArray[0]}, {...bidArray[1]}]; + const bids = [{ ...bidArray[0] }, { ...bidArray[1] }]; - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2 }] }); targetBidPoolHook(callbackFn, bids, getHighestCpm); bids.pop(); @@ -575,13 +575,13 @@ describe('multibid adapter', function () { }); it('it sorts and creates dynamic alias on bidsReceived if multibid configuration found with prefix', function () { - const modifiedBids = [{...bidArray[1]}, {...bidArray[0]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test.div', {...bid}); + const modifiedBids = [{ ...bidArray[1] }, { ...bidArray[0] }].map(bid => { + addBidResponseHook(bidResponseCallback, 'test.div', { ...bid }); return bidResult; }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); targetBidPoolHook(callbackFn, modifiedBids, getHighestCpm); @@ -600,13 +600,13 @@ describe('multibid adapter', function () { }); it('it sorts by cpm treating dynamic alias as unique bid when no bid limit defined', function () { - const modifiedBids = [{...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}, {...bidArrayAlt[1]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test.div', {...bid}); + const modifiedBids = [{ ...bidArrayAlt[0] }, { ...bidArrayAlt[2] }, { ...bidArrayAlt[3] }, { ...bidArrayAlt[1] }].map(bid => { + addBidResponseHook(bidResponseCallback, 'test.div', { ...bid }); return bidResult; }); - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); targetBidPoolHook(callbackFn, modifiedBids, getHighestCpm); @@ -633,13 +633,13 @@ describe('multibid adapter', function () { }); it('it should filter out dynamic bid when bid limit is less than unique bid pool', function () { - const modifiedBids = [{...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}, {...bidArrayAlt[1]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test.div', {...bid}); + const modifiedBids = [{ ...bidArrayAlt[0] }, { ...bidArrayAlt[2] }, { ...bidArrayAlt[3] }, { ...bidArrayAlt[1] }].map(bid => { + addBidResponseHook(bidResponseCallback, 'test.div', { ...bid }); return bidResult; }); - config.setConfig({ multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}] }); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); targetBidPoolHook(callbackFn, modifiedBids, getHighestCpm, 3); @@ -657,15 +657,15 @@ describe('multibid adapter', function () { }); it('it should collect all bids from auction and bid cache then sort and filter', function () { - config.setConfig({ multibid: [{bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA'}] }); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 2, targetBiddercodePrefix: 'bidA' }] }); - const modifiedBids = [{...bidArrayAlt[0]}, {...bidArrayAlt[2]}, {...bidArrayAlt[3]}, {...bidArrayAlt[1]}].map(bid => { - addBidResponseHook(bidResponseCallback, 'test.div', {...bid}); + const modifiedBids = [{ ...bidArrayAlt[0] }, { ...bidArrayAlt[2] }, { ...bidArrayAlt[3] }, { ...bidArrayAlt[1] }].map(bid => { + addBidResponseHook(bidResponseCallback, 'test.div', { ...bid }); return bidResult; }); - const bidPool = [].concat.apply(modifiedBids, [{...bidCacheArray[0]}, {...bidCacheArray[1]}]); + const bidPool = [].concat.apply(modifiedBids, [{ ...bidCacheArray[0] }, { ...bidCacheArray[1] }]); expect(bidPool.length).to.equal(6); @@ -688,53 +688,53 @@ describe('multibid adapter', function () { describe('validate multibid', function () { it('should fail validation for missing bidder name in entry', function () { - const conf = [{maxBids: 1}]; + const conf = [{ maxBids: 1 }]; const result = validateMultibid(conf); expect(result).to.equal(false); }); it('should pass validation on all multibid entries', function () { - const conf = [{bidder: 'bidderA', maxBids: 1}, {bidder: 'bidderB', maxBids: 2}]; + const conf = [{ bidder: 'bidderA', maxBids: 1 }, { bidder: 'bidderB', maxBids: 2 }]; const result = validateMultibid(conf); expect(result).to.equal(true); }); it('should fail validation for maxbids less than 1 in entry', function () { - const conf = [{bidder: 'bidderA', maxBids: 0}, {bidder: 'bidderB', maxBids: 2}]; + const conf = [{ bidder: 'bidderA', maxBids: 0 }, { bidder: 'bidderB', maxBids: 2 }]; const result = validateMultibid(conf); expect(result).to.equal(false); }); it('should fail validation for maxbids greater than 9 in entry', function () { - const conf = [{bidder: 'bidderA', maxBids: 10}, {bidder: 'bidderB', maxBids: 2}]; + const conf = [{ bidder: 'bidderA', maxBids: 10 }, { bidder: 'bidderB', maxBids: 2 }]; const result = validateMultibid(conf); expect(result).to.equal(false); }); it('should add multbid entries to global config', function () { - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 1}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 1 }] }); const conf = config.getConfig('multibid'); - expect(conf).to.deep.equal([{bidder: 'bidderA', maxBids: 1}]); + expect(conf).to.deep.equal([{ bidder: 'bidderA', maxBids: 1 }]); }); it('should modify multbid entries and add to global config', function () { - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 0}, {bidder: 'bidderB', maxBids: 15}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 0 }, { bidder: 'bidderB', maxBids: 15 }] }); const conf = config.getConfig('multibid'); - expect(conf).to.deep.equal([{bidder: 'bidderA', maxBids: 1}, {bidder: 'bidderB', maxBids: 9}]); + expect(conf).to.deep.equal([{ bidder: 'bidderA', maxBids: 1 }, { bidder: 'bidderB', maxBids: 9 }]); }); it('should filter multbid entry and add modified to global config', function () { - config.setConfig({multibid: [{bidder: 'bidderA', maxBids: 0}, {maxBids: 15}]}); + config.setConfig({ multibid: [{ bidder: 'bidderA', maxBids: 0 }, { maxBids: 15 }] }); const conf = config.getConfig('multibid'); expect(conf.length).to.equal(1); - expect(conf).to.deep.equal([{bidder: 'bidderA', maxBids: 1}]); + expect(conf).to.deep.equal([{ bidder: 'bidderA', maxBids: 1 }]); }); }); diff --git a/test/spec/modules/mwOpenLinkIdSystem_spec.js b/test/spec/modules/mwOpenLinkIdSystem_spec.js index fb082b8cd16..55bea0ea24f 100644 --- a/test/spec/modules/mwOpenLinkIdSystem_spec.js +++ b/test/spec/modules/mwOpenLinkIdSystem_spec.js @@ -13,8 +13,8 @@ describe('mwOpenLinkId module', function () { }); it('getId() should return a MediaWallah openLink Id when the MediaWallah openLink first party cookie exists', function () { - writeCookie({eid: 'XX-YY-ZZ-123'}); + writeCookie({ eid: 'XX-YY-ZZ-123' }); const id = mwOpenLinkIdSubModule.getId(P_CONFIG_MOCK); - expect(id).to.be.deep.equal({id: {eid: 'XX-YY-ZZ-123'}}); + expect(id).to.be.deep.equal({ id: { eid: 'XX-YY-ZZ-123' } }); }); }); diff --git a/test/spec/modules/my6senseBidAdapter_spec.js b/test/spec/modules/my6senseBidAdapter_spec.js index 9493b104680..be075537de3 100644 --- a/test/spec/modules/my6senseBidAdapter_spec.js +++ b/test/spec/modules/my6senseBidAdapter_spec.js @@ -105,7 +105,7 @@ describe('My6sense Bid adapter test', function () { }); describe('test bid responses', function () { it('success 1', function () { - var bids = spec.interpretResponse(serverResponses[0], {'bidRequest': bidRequests[0]}); + var bids = spec.interpretResponse(serverResponses[0], { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(1); expect(bids[0].cpm).to.equal(1.5); expect(bids[0].width).to.equal(300); diff --git a/test/spec/modules/mycodemediaBidAdapter_spec.js b/test/spec/modules/mycodemediaBidAdapter_spec.js index 7cc9b412ea0..fbf40f4b403 100644 --- a/test/spec/modules/mycodemediaBidAdapter_spec.js +++ b/test/spec/modules/mycodemediaBidAdapter_spec.js @@ -478,7 +478,7 @@ describe('MyCodeMediaBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -487,9 +487,7 @@ describe('MyCodeMediaBidAdapter', function () { expect(syncData[0].url).to.equal('https://usersync.mycodemedia.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -498,7 +496,7 @@ describe('MyCodeMediaBidAdapter', function () { expect(syncData[0].url).to.equal('https://usersync.mycodemedia.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/mygaruIdSystem_spec.js b/test/spec/modules/mygaruIdSystem_spec.js index 44075713a85..46fb811cc30 100644 --- a/test/spec/modules/mygaruIdSystem_spec.js +++ b/test/spec/modules/mygaruIdSystem_spec.js @@ -21,7 +21,7 @@ describe('MygaruID module', function () { await promise; expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.calledWith({mygaruId: '123'})).to.be.true; + expect(callBackSpy.calledWith({ mygaruId: '123' })).to.be.true; }); it('should not fail on error', async () => { const callBackSpy = sinon.spy(); @@ -42,7 +42,7 @@ describe('MygaruID module', function () { await promise; expect(callBackSpy.calledOnce).to.be.true; - expect(callBackSpy.calledWith({mygaruId: undefined})).to.be.true; + expect(callBackSpy.calledWith({ mygaruId: undefined })).to.be.true; }); it('should not modify while decoding', () => { diff --git a/test/spec/modules/netIdSystem_spec.js b/test/spec/modules/netIdSystem_spec.js index bbf59c39f32..2cd68677627 100644 --- a/test/spec/modules/netIdSystem_spec.js +++ b/test/spec/modules/netIdSystem_spec.js @@ -1,7 +1,7 @@ -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {netIdSubmodule} from '../../../modules/netIdSystem.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { netIdSubmodule } from '../../../modules/netIdSystem.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; describe('Net ID', () => { describe('eid', () => { @@ -16,7 +16,7 @@ describe('Net ID', () => { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'netid.de', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); }); diff --git a/test/spec/modules/neuwoRtdProvider_spec.js b/test/spec/modules/neuwoRtdProvider_spec.js index 4b2951afe33..bb64b283535 100644 --- a/test/spec/modules/neuwoRtdProvider_spec.js +++ b/test/spec/modules/neuwoRtdProvider_spec.js @@ -1,10 +1,12 @@ import * as neuwo from "modules/neuwoRtdProvider"; +import * as refererDetection from "src/refererDetection.js"; import { server } from "test/mocks/xhr.js"; -const NEUWO_API_URL = "https://api.url.neuwo.ai/edge/GetAiTopics"; +const NEUWO_API_URL = "https://edge.neuwo.ai/api/aitopics/edge/v1/iab"; const NEUWO_API_TOKEN = "token"; -const IAB_CONTENT_TAXONOMY_VERSION = "3.0"; +const IAB_CONTENT_TAXONOMY_VERSION = "2.2"; +// API config const config = () => ({ params: { neuwoApiUrl: NEUWO_API_URL, @@ -13,7 +15,115 @@ const config = () => ({ }, }); +/** + * API Response Mock + * Returns new format with segtax-based structure + * Field names: id, name, relevance (lowercase) + * Structure: { "6": { "1": [...], "2": [...] }, "4": { "3": [...] } } + */ function getNeuwoApiResponse() { + return { + 7: { + 1: [ + { + id: "80DV8O", + }, + { + id: "52", + }, + { + id: "432", + }, + ], + 2: [ + { + id: "90", + }, + ], + 3: [ + { + id: "106", + }, + ], + }, + 1: { + 1: [ + { + id: "IAB12", + }, + ], + }, + 6: { + 1: [ + { + id: "52", + }, + ], + 2: [ + { + id: "90", + }, + { + id: "434", + }, + ], + 3: [ + { + id: "106", + }, + ], + }, + 4: { + 3: [ + { + id: "49", + }, + { + id: "780", + }, + ], + 4: [ + { + id: "431", + }, + { + id: "196", + }, + { + id: "197", + }, + ], + 5: [ + { + id: "98", + }, + ], + }, + }; +} + +// ============================================================================ +// V1 API Constants and Mocks +// ============================================================================ + +const NEUWO_API_URL_V1 = "https://api.url.neuwo.ai/edge/GetAiTopics"; +const IAB_CONTENT_TAXONOMY_VERSION_V1 = "3.0"; + +// Legacy V1 API config (for backward compatibility tests) +const configV1 = () => ({ + params: { + neuwoApiUrl: NEUWO_API_URL_V1, + neuwoApiToken: NEUWO_API_TOKEN, + iabContentTaxonomyVersion: IAB_CONTENT_TAXONOMY_VERSION_V1, + }, +}); + +/** + * V1 API Response Mock + * Returns legacy format with marketing_categories structure + * Field names: ID, label, relevance (capital letters) + */ +function getNeuwoApiResponseV1() { return { brand_safety: { BS_score: "1.0", @@ -65,8 +175,6 @@ function getNeuwoApiResponse() { ], }; } -const CONTENT_TIERS = ["iab_tier_1", "iab_tier_2", "iab_tier_3"]; -const AUDIENCE_TIERS = ["iab_audience_tier_3", "iab_audience_tier_4", "iab_audience_tier_5"]; /** * Object generator, like above, written using alternative techniques @@ -126,38 +234,20 @@ describe("neuwoRtdModule", function () { }); describe("buildIabData", function () { - it("should return an empty segment array when no matching tiers are found", function () { - const marketingCategories = getNeuwoApiResponse().marketing_categories; - const tiers = ["non_existent_tier"]; - const segtax = 0; - const result = neuwo.buildIabData(marketingCategories, tiers, segtax); - const expected = { - name: neuwo.DATA_PROVIDER, - segment: [], - ext: { - segtax, - }, - }; - expect(result, "should produce a valid object with an empty segment array").to.deep.equal( - expected - ); - }); - it("should correctly build the data object for content tiers", function () { - const marketingCategories = getNeuwoApiResponse().marketing_categories; + // format with tier keys "1", "2", "3" + const tierData = { + "1": [{ id: "274", name: "Home & Garden", relevance: "0.47" }], + "2": [{ id: "216", name: "Cooking", relevance: "0.41" }], + "3": [], + }; const segtax = 0; - const result = neuwo.buildIabData(marketingCategories, CONTENT_TIERS, segtax); + const result = neuwo.buildIabData(tierData, segtax); const expected = { name: neuwo.DATA_PROVIDER, segment: [ - { - id: "274", - name: "Home & Garden", - }, - { - id: "216", - name: "Cooking", - }, + { id: "274" }, + { id: "216" }, ], ext: { segtax, @@ -169,24 +259,20 @@ describe("neuwoRtdModule", function () { }); it("should correctly build the data object for audience tiers", function () { - const marketingCategories = getNeuwoApiResponse().marketing_categories; + // format with tier keys "3", "4", "5" for audience + const tierData = { + "3": [{ id: "49", name: "Demographic | Gender | Female |", relevance: "0.9923" }], + "4": [{ id: "127", name: "Demographic | Household Data | 1 Child |", relevance: "0.9673" }], + "5": [{ id: "98", name: "Demographic | Household Data | Parents with Children |", relevance: "0.9066" }], + }; const segtax = 0; - const result = neuwo.buildIabData(marketingCategories, AUDIENCE_TIERS, segtax); + const result = neuwo.buildIabData(tierData, segtax); const expected = { name: neuwo.DATA_PROVIDER, segment: [ - { - id: "49", - name: "Demographic | Gender | Female |", - }, - { - id: "127", - name: "Demographic | Household Data | 1 Child |", - }, - { - id: "98", - name: "Demographic | Household Data | Parents with Children |", - }, + { id: "49" }, + { id: "127" }, + { id: "98" }, ], ext: { segtax, @@ -197,7 +283,7 @@ describe("neuwoRtdModule", function () { ); }); - it("should return an empty segment array when marketingCategories is null or undefined", function () { + it("should return an empty segment array when tierData is null or undefined", function () { const segtax = 4; const expected = { name: neuwo.DATA_PROVIDER, @@ -207,19 +293,19 @@ describe("neuwoRtdModule", function () { }, }; expect( - neuwo.buildIabData(null, CONTENT_TIERS, segtax), - "should handle null marketingCategories gracefully" + neuwo.buildIabData(null, segtax), + "should handle null tierData gracefully" ).to.deep.equal(expected); expect( - neuwo.buildIabData(undefined, CONTENT_TIERS, segtax), - "should handle undefined marketingCategories gracefully" + neuwo.buildIabData(undefined, segtax), + "should handle undefined tierData gracefully" ).to.deep.equal(expected); }); - it("should return an empty segment array when marketingCategories is empty", function () { - const marketingCategories = {}; + it("should return an empty segment array when tierData is empty", function () { + const tierData = {}; const segtax = 4; - const result = neuwo.buildIabData(marketingCategories, CONTENT_TIERS, segtax); + const result = neuwo.buildIabData(tierData, segtax); const expected = { name: neuwo.DATA_PROVIDER, segment: [], @@ -227,23 +313,23 @@ describe("neuwoRtdModule", function () { segtax, }, }; - expect(result, "should handle an empty marketingCategories object").to.deep.equal(expected); + expect(result, "should handle an empty tierData object").to.deep.equal(expected); }); - it("should gracefully handle if a marketing_categories key contains a non-array value", function () { - const marketingCategories = getNeuwoApiResponse().marketing_categories; - // Overwrite iab_tier_1 to be an object instead of an array - marketingCategories.iab_tier_1 = { ID: "274", label: "Home & Garden" }; + it("should gracefully handle if a tier key contains a non-array value", function () { + const tierData = { + "1": { id: "274", name: "Home & Garden" }, // Not an array + "2": [{ id: "216", name: "Cooking", relevance: "0.41" }], + }; const segtax = 4; - const result = neuwo.buildIabData(marketingCategories, CONTENT_TIERS, segtax); + const result = neuwo.buildIabData(tierData, segtax); const expected = { name: neuwo.DATA_PROVIDER, - // The segment should only contain data from the valid iab_tier_2 + // The segment should only contain data from the valid tier "2" segment: [ { id: "216", - name: "Cooking", }, ], ext: { @@ -257,30 +343,29 @@ describe("neuwoRtdModule", function () { }); it("should ignore malformed objects within a tier array", function () { - const marketingCategories = getNeuwoApiResponse().marketing_categories; - // Overwrite iab_tier_1 with various malformed objects - marketingCategories.iab_tier_1 = [ - { ID: "274", label: "Valid Object" }, - { ID: "999" }, // Missing 'label' property - { label: "Another Label" }, // Missing 'ID' property - null, // A null value - "just-a-string", // A string primitive - {}, // An empty object - ]; + // Tier "1" with various malformed objects + const tierData = { + "1": [ + { id: "274", name: "Valid Object" }, + { name: "Another Label" }, // Missing 'id' property + null, // A null value + "just-a-string", // A string primitive + {}, // An empty object + ], + "2": [{ id: "216", name: "Cooking", relevance: "0.41" }], + }; const segtax = 4; - const result = neuwo.buildIabData(marketingCategories, CONTENT_TIERS, segtax); + const result = neuwo.buildIabData(tierData, segtax); const expected = { name: neuwo.DATA_PROVIDER, - // The segment should contain the one valid object from iab_tier_1 and the data from iab_tier_2 + // The segment should contain the one valid object from tier "1" and the data from tier "2" segment: [ { id: "274", - name: "Valid Object", }, { id: "216", - name: "Cooking", }, ], ext: { @@ -293,7 +378,7 @@ describe("neuwoRtdModule", function () { ); }); - it("should return an empty segment array if the entire marketingCategories object is not a valid object", function () { + it("should return an empty segment array if the entire tierData is not a valid object", function () { const segtax = 4; const expected = { name: neuwo.DATA_PROVIDER, @@ -301,1000 +386,3636 @@ describe("neuwoRtdModule", function () { ext: { segtax }, }; // Test with a string - const resultString = neuwo.buildIabData("incorrect format", CONTENT_TIERS, segtax); - expect(resultString, "should handle non-object marketingCategories input").to.deep.equal( + const resultString = neuwo.buildIabData("incorrect format", segtax); + expect(resultString, "should handle non-object tierData input").to.deep.equal( expected ); }); }); - describe("injectOrtbData", function () { - it("should correctly mutate the request bids config object with new data", function () { - const reqBidsConfigObj = { ortb2Fragments: { global: {} } }; - neuwo.injectOrtbData(reqBidsConfigObj, "c.d.e.f", { g: "h" }); - expect( - reqBidsConfigObj.ortb2Fragments.global.c.d.e.f.g, - "should deeply merge the new data into the target object" - ).to.equal("h"); + describe("buildFilterQueryParams", function () { + it("should return empty array when no filters provided", function () { + const result = neuwo.buildFilterQueryParams(null, 6); + expect(result, "should return empty array for null filters").to.deep.equal([]); }); - }); - - describe("getBidRequestData", function () { - describe("when using IAB Content Taxonomy 3.0", function () { - it("should correctly structure the bids object after a successful API response", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig = bidsConfiglike(); - const conf = config(); - // control xhr api request target for testing - conf.params.websiteToAnalyseUrl = - "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + it("should return empty array when filters parameter is undefined", function () { + const result = neuwo.buildFilterQueryParams(undefined, 6); + expect(result, "should return empty array for undefined filters").to.deep.equal([]); + }); - expect(request.url, "The request URL should be a string").to.be.a("string"); - expect(request.url, "The request URL should include the public API token").to.include( - conf.params.neuwoApiToken - ); - expect(request.url, "The request URL should include the encoded website URL").to.include( - encodeURIComponent(conf.params.websiteToAnalyseUrl) - ); + it("should return empty array when filters is empty object", function () { + const result = neuwo.buildFilterQueryParams({}, 6); + expect(result, "should return empty array for empty filters").to.deep.equal([]); + }); - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + it("should convert ContentTier1 filter correctly", function () { + const filters = { + ContentTier1: { limit: 3, threshold: 0.5 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; - expect(contentData.name, "The data provider name should be correctly set").to.equal( - neuwo.DATA_PROVIDER - ); - expect( - contentData.ext.segtax, - "The segtax value should correspond to IAB Content Taxonomy 3.0" - ).to.equal(7); - expect( - contentData.segment[0].id, - "The first segment ID should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_1[0].ID); - expect( - contentData.segment[1].name, - "The second segment name should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_2[0].label); - }); + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.have.lengthOf(2); }); - describe("when using IAB Content Taxonomy 2.2", function () { - it("should correctly structure the bids object after a successful API response", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.iabContentTaxonomyVersion = "2.2"; - // control xhr api request target for testing - conf.params.websiteToAnalyseUrl = - "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + it("should convert ContentTier2 filter correctly", function () { + const filters = { + ContentTier2: { limit: 5, threshold: 0.6 } + }; + const contentSegtax = 7; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + expect(result).to.include("filter_7_2_limit=5"); + expect(result).to.include("filter_7_2_threshold=0.6"); + expect(result).to.have.lengthOf(2); + }); - expect(request.url, "The request URL should be a string").to.be.a("string"); - expect(request.url, "The request URL should include the public API token").to.include( - conf.params.neuwoApiToken - ); - expect(request.url, "The request URL should include the encoded website URL").to.include( - encodeURIComponent(conf.params.websiteToAnalyseUrl) - ); + it("should convert ContentTier3 filter correctly", function () { + const filters = { + ContentTier3: { limit: 4, threshold: 0.8 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); - const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; - expect(contentData.name, "The data provider name should be correctly set").to.equal( - neuwo.DATA_PROVIDER - ); - expect( - contentData.ext.segtax, - "The segtax value should correspond to IAB Content Taxonomy 2.2" - ).to.equal(6); - expect( - contentData.segment[0].id, - "The first segment ID should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_1[0].ID); - expect( - contentData.segment[1].name, - "The second segment name should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_2[0].label); - }); + expect(result).to.include("filter_6_3_limit=4"); + expect(result).to.include("filter_6_3_threshold=0.8"); + expect(result).to.have.lengthOf(2); }); - describe("when using the default IAB Content Taxonomy", function () { - it("should correctly structure the bids object after a successful API response", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.iabContentTaxonomyVersion = undefined; - // control xhr api request target for testing - conf.params.websiteToAnalyseUrl = - "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + it("should convert AudienceTier3 filter correctly", function () { + const filters = { + AudienceTier3: { limit: 2, threshold: 0.9 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.include("filter_4_3_threshold=0.9"); + expect(result).to.have.lengthOf(2); + }); - expect(request.url, "The request URL should be a string").to.be.a("string"); - expect(request.url, "The request URL should include the public API token").to.include( - conf.params.neuwoApiToken - ); - expect(request.url, "The request URL should include the encoded website URL").to.include( - encodeURIComponent(conf.params.websiteToAnalyseUrl) - ); + it("should convert AudienceTier4 filter correctly", function () { + const filters = { + AudienceTier4: { limit: 10, threshold: 0.85 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); - const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; - expect(contentData.name, "The data provider name should be correctly set").to.equal( - neuwo.DATA_PROVIDER - ); - expect( - contentData.ext.segtax, - "The segtax value should default to IAB Content Taxonomy 3.0" - ).to.equal(7); - expect( - contentData.segment[0].id, - "The first segment ID should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_1[0].ID); - expect( - contentData.segment[1].name, - "The second segment name should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_tier_2[0].label); - }); + expect(result).to.include("filter_4_4_limit=10"); + expect(result).to.include("filter_4_4_threshold=0.85"); + expect(result).to.have.lengthOf(2); }); - describe("when using IAB Audience Taxonomy 1.1", function () { - it("should correctly structure the bids object after a successful API response", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig = bidsConfiglike(); - const conf = config(); - // control xhr api request target for testing - conf.params.websiteToAnalyseUrl = - "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + it("should convert AudienceTier5 filter correctly", function () { + const filters = { + AudienceTier5: { limit: 7, threshold: 0.95 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + expect(result).to.include("filter_4_5_limit=7"); + expect(result).to.include("filter_4_5_threshold=0.95"); + expect(result).to.have.lengthOf(2); + }); - expect(request.url, "The request URL should be a string").to.be.a("string"); - expect(request.url, "The request URL should include the public API token").to.include( - conf.params.neuwoApiToken - ); - expect(request.url, "The request URL should include the encoded website URL").to.include( - encodeURIComponent(conf.params.websiteToAnalyseUrl) - ); + it("should handle multiple content tiers with same segtax", function () { + const filters = { + ContentTier1: { limit: 3 }, + ContentTier2: { limit: 5 }, + ContentTier3: { threshold: 0.7 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); - const userData = bidsConfig.ortb2Fragments.global.user.data[0]; - expect(userData.name, "The data provider name should be correctly set").to.equal( - neuwo.DATA_PROVIDER - ); - expect( - userData.ext.segtax, - "The segtax value should correspond to IAB Audience Taxonomy 1.1" - ).to.equal(4); - expect( - userData.segment[0].id, - "The first segment ID should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_audience_tier_3[0].ID); - expect( - userData.segment[1].name, - "The second segment name should match the API response" - ).to.equal(apiResponse.marketing_categories.iab_audience_tier_4[0].label); - }); + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_6_3_threshold=0.7"); + expect(result).to.have.lengthOf(3); }); - it("should not change the bids object structure after an unsuccessful API response", function () { - const bidsConfig = bidsConfiglike(); - const bidsConfigCopy = bidsConfiglike(); - const conf = config(); + it("should handle multiple audience tiers", function () { + const filters = { + AudienceTier3: { limit: 2 }, + AudienceTier4: { limit: 4 }, + AudienceTier5: { threshold: 0.85 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; - request.respond( - 404, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify({ detail: "test error" }) - ); - expect( - bidsConfig, - "The bids config object should remain unmodified after a failed API call" - ).to.deep.equal(bidsConfigCopy); + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.include("filter_4_4_limit=4"); + expect(result).to.include("filter_4_5_threshold=0.85"); + expect(result).to.have.lengthOf(3); }); - }); - - describe("cleanUrl", function () { - describe("when no stripping options are provided", function () { - it("should return the URL unchanged", function () { - const url = "https://example.com/page?foo=bar&baz=qux"; - const result = neuwo.cleanUrl(url, {}); - expect(result, "should return the original URL with all query params intact").to.equal(url); - }); - it("should return the URL unchanged when options object is empty", function () { - const url = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url); - expect(result, "should handle missing options parameter").to.equal(url); - }); + it("should handle both content and audience tiers together", function () { + const filters = { + ContentTier1: { limit: 3, threshold: 0.5 }, + ContentTier2: { limit: 5 }, + AudienceTier3: { limit: 2, threshold: 0.9 }, + AudienceTier4: { threshold: 0.8 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.include("filter_4_3_threshold=0.9"); + expect(result).to.include("filter_4_4_threshold=0.8"); + expect(result).to.have.lengthOf(6); }); - describe("with query parameters edge cases", function () { - it("should strip all query parameters from the URL for `stripAllQueryParams` (edge cases)", function () { - const stripAll = (url) => neuwo.cleanUrl(url, { stripAllQueryParams: true }); - const expected = "https://example.com/page"; - const expectedWithFragment = "https://example.com/page#anchor"; - - // Basic formats - expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); - expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); - expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); - expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); - - // Multiple parameters - expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); - expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + it("should use different content segtax values correctly", function () { + const filters = { + ContentTier1: { limit: 3 } + }; - // Special characters and encoding - expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); - expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); - expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + // Test with segtax 6 (IAB 2.2) + const result6 = neuwo.buildFilterQueryParams(filters, 6, false); + expect(result6).to.include("filter_6_1_limit=3"); + expect(result6).to.not.include("filter_7_1_limit=3"); - // Delimiters and syntax edge cases - expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); - expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + // Test with segtax 7 (IAB 3.0) + const result7 = neuwo.buildFilterQueryParams(filters, 7, false); + expect(result7).to.include("filter_7_1_limit=3"); + expect(result7).to.not.include("filter_6_1_limit=3"); + }); - // Empty and missing cases - expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); - expect(stripAll("https://example.com/page??"), "should remove double question mark").to.equal(expected); - expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + it("should ignore unknown tier names", function () { + const filters = { + ContentTier1: { limit: 3 }, + UnknownTier: { limit: 10 }, + InvalidTier99: { threshold: 0.5 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Unicode and special values - expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); - expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); - expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.have.lengthOf(1); + }); - // Fragment positioning (fragments are preserved by default) - expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); - expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); - }); + it("should handle filters with only limit property", function () { + const filters = { + ContentTier1: { limit: 5 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - it("should strip all query parameters from the URL for `stripQueryParamsForDomains` (edge cases)", function () { - const stripAll = (url) => neuwo.cleanUrl(url, { stripQueryParamsForDomains: ["example.com"] }); - const expected = "https://example.com/page"; - const expectedWithFragment = "https://example.com/page#anchor"; + expect(result).to.include("filter_6_1_limit=5"); + expect(result).to.not.include.match(/filter_6_1_threshold/); + expect(result).to.have.lengthOf(1); + }); - // Basic formats - expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); - expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); - expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); - expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); + it("should handle filters with only threshold property", function () { + const filters = { + AudienceTier3: { threshold: 0.75 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Multiple parameters - expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); - expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + expect(result).to.include("filter_4_3_threshold=0.75"); + expect(result).to.not.include.match(/filter_4_3_limit/); + expect(result).to.have.lengthOf(1); + }); - // Special characters and encoding - expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); - expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); - expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + it("should handle filters with additional custom properties", function () { + const filters = { + ContentTier1: { limit: 3, threshold: 0.5, customProp: "value" } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Delimiters and syntax edge cases - expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); - expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.include("filter_6_1_customProp=value"); + expect(result).to.have.lengthOf(3); + }); - // Empty and missing cases - expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); - expect(stripAll("https://example.com/page??"), "should remove double question mark").to.equal(expected); - expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + it("should handle empty filter objects for tiers", function () { + const filters = { + ContentTier1: {}, + AudienceTier3: {} + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Unicode and special values - expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); - expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); - expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + expect(result).to.have.lengthOf(0); + }); - // Fragment positioning (fragments are preserved by default) - expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); - expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); - }); + it("should not include null limit value", function () { + const filters = { + ContentTier1: { limit: null, threshold: 0.5 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - it("should strip all query parameters from the URL for `stripQueryParams` (edge cases)", function () { - const stripAll = (url) => neuwo.cleanUrl(url, { stripQueryParams: ["key", "key1", "key2", "", "?"] }); - const expected = "https://example.com/page"; - const expectedWithFragment = "https://example.com/page#anchor"; + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.have.lengthOf(1); + }); - // Basic formats - expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); - expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); - expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); - expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); + it("should not include undefined limit value", function () { + const filters = { + ContentTier1: { limit: undefined, threshold: 0.5 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Multiple parameters - expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); - expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.have.lengthOf(1); + }); - // Special characters and encoding - expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); - expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); - expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); - expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + it("should not include null threshold value", function () { + const filters = { + AudienceTier3: { limit: 5, threshold: null } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Delimiters and syntax edge cases - expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); - expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); - expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + expect(result).to.include("filter_4_3_limit=5"); + expect(result).to.have.lengthOf(1); + }); - // Empty and missing cases - expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); - expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + it("should not include undefined threshold value", function () { + const filters = { + AudienceTier3: { limit: 5, threshold: undefined } + }; + const result = neuwo.buildFilterQueryParams(filters, 6, false); - // Unicode and special values - expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); - expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); - expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + expect(result).to.include("filter_4_3_limit=5"); + expect(result).to.have.lengthOf(1); + }); - // Fragment positioning (fragments are preserved by default) - expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); - expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); + // OpenRTB 2.5 Feature Tests + describe("with enableOrtb25Fields enabled (default)", function () { + it("should add IAB 1.0 filter params when ContentTier1 filter is provided", function () { + const filters = { + ContentTier1: { limit: 3, threshold: 0.5 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.include("filter_1_1_limit=3"); + expect(result).to.include("filter_1_1_threshold=0.5"); + expect(result).to.have.lengthOf(4); }); - }); - describe("when stripAllQueryParams is true", function () { - it("should strip all query parameters from the URL", function () { - const url = "https://example.com/page?foo=bar&baz=qux&test=123"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); - expect(result, "should remove all query parameters").to.equal(expected); + it("should add IAB 1.0 filter params when ContentTier2 filter is provided", function () { + const filters = { + ContentTier2: { limit: 5, threshold: 0.6 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax); + + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_6_2_threshold=0.6"); + expect(result).to.include("filter_1_2_limit=5"); + expect(result).to.include("filter_1_2_threshold=0.6"); + expect(result).to.have.lengthOf(4); }); - it("should return the URL unchanged if there are no query parameters", function () { - const url = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); - expect(result, "should handle URLs without query params").to.equal(url); + it("should add IAB 1.0 filter params for both ContentTier1 and ContentTier2", function () { + const filters = { + ContentTier1: { limit: 3 }, + ContentTier2: { limit: 5 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_1_1_limit=3"); + expect(result).to.include("filter_1_2_limit=5"); + expect(result).to.have.lengthOf(4); }); - it("should preserve the hash fragment when stripping query params without stripFragments", function () { - const url = "https://example.com/page?foo=bar#section"; - const expected = "https://example.com/page#section"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); - expect(result, "should preserve hash fragments by default").to.equal(expected); + it("should NOT add ContentTier3 filter to IAB 1.0 (only tiers 1-2 exist)", function () { + const filters = { + ContentTier1: { limit: 3 }, + ContentTier2: { limit: 5 }, + ContentTier3: { threshold: 0.7 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_6_3_threshold=0.7"); + expect(result).to.include("filter_1_1_limit=3"); + expect(result).to.include("filter_1_2_limit=5"); + expect(result).to.not.include.match(/filter_1_3/); + expect(result).to.have.lengthOf(5); }); - it("should strip hash fragment when stripFragments is enabled", function () { - const url = "https://example.com/page?foo=bar#section"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true, stripFragments: true }); - expect(result, "should strip both query params and fragments").to.equal(expected); + it("should NOT add audience tier filters to IAB 1.0", function () { + const filters = { + AudienceTier3: { limit: 2 }, + AudienceTier4: { limit: 4 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6); + + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.include("filter_4_4_limit=4"); + expect(result).to.not.include.match(/filter_1/); + expect(result).to.have.lengthOf(2); }); - it("should strip query params but preserve path and protocol", function () { - const url = "https://subdomain.example.com:8080/path/to/page?param=value"; - const expected = "https://subdomain.example.com:8080/path/to/page"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); - expect(result, "should preserve protocol, domain, port, and path").to.equal(expected); + it("should add IAB 1.0 filter params alongside audience filters", function () { + const filters = { + ContentTier1: { limit: 3 }, + AudienceTier3: { limit: 2 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_1_1_limit=3"); + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.have.lengthOf(3); }); - }); - describe("when stripQueryParamsForDomains is provided", function () { - it("should strip all query params for exact domain match", function () { - const url = "https://example.com/page?foo=bar&baz=qux"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"] - }); - expect(result, "should strip params for exact domain match").to.equal(expected); + it("should not add segtax 1 params when no content filters are provided", function () { + const filters = { + AudienceTier3: { limit: 2 } + }; + const result = neuwo.buildFilterQueryParams(filters, 6); + + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.not.include.match(/filter_1/); + expect(result).to.have.lengthOf(1); }); - it("should strip all query params for subdomain match", function () { - const url = "https://sub.example.com/page?foo=bar"; - const expected = "https://sub.example.com/page"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"] - }); - expect(result, "should strip params for subdomains").to.equal(expected); + it("should not add segtax 1 params when filters is empty", function () { + const result = neuwo.buildFilterQueryParams({}, 6); + + expect(result).to.deep.equal([]); }); - it("should not strip query params if domain does not match", function () { - const url = "https://other.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"] - }); - expect(result, "should preserve params for non-matching domains").to.equal(url); + it("should not add segtax 1 params when filters is null", function () { + const result = neuwo.buildFilterQueryParams(null, 6); + + expect(result).to.deep.equal([]); }); - it("should not strip query params if subdomain is provided for domain", function () { - const url = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["sub.example.com"] - }); - expect(result, "should preserve params for domain when subdomain is provided").to.equal(url); + it("should work with different content segtax values", function () { + const filters = { + ContentTier1: { limit: 3 } + }; + + // Test with segtax 7 (IAB 3.0) + const result7 = neuwo.buildFilterQueryParams(filters, 7); + expect(result7).to.include("filter_7_1_limit=3"); + expect(result7).to.include("filter_1_1_limit=3"); + expect(result7).to.have.lengthOf(2); }); - it("should handle multiple domains in the list", function () { - const url1 = "https://example.com/page?foo=bar"; - const url2 = "https://test.com/page?foo=bar"; - const url3 = "https://other.com/page?foo=bar"; - const domains = ["example.com", "test.com"]; + it("should not produce duplicate query params when contentSegtax is 1", function () { + const filters = { + ContentTier1: { limit: 5, threshold: 0.8 }, + ContentTier2: { limit: 3 } + }; - const result1 = neuwo.cleanUrl(url1, { stripQueryParamsForDomains: domains }); - const result2 = neuwo.cleanUrl(url2, { stripQueryParamsForDomains: domains }); - const result3 = neuwo.cleanUrl(url3, { stripQueryParamsForDomains: domains }); + const result = neuwo.buildFilterQueryParams(filters, 1); - expect(result1, "should strip params for first domain").to.equal("https://example.com/page"); - expect(result2, "should strip params for second domain").to.equal("https://test.com/page"); - expect(result3, "should preserve params for non-listed domain").to.equal(url3); + // Count occurrences of each param to verify no duplicates + const countOccurrences = (arr, val) => arr.filter(p => p === val).length; + expect(countOccurrences(result, "filter_1_1_limit=5"), "filter_1_1_limit should appear once").to.equal(1); + expect(countOccurrences(result, "filter_1_1_threshold=0.8"), "filter_1_1_threshold should appear once").to.equal(1); + expect(countOccurrences(result, "filter_1_2_limit=3"), "filter_1_2_limit should appear once").to.equal(1); + expect(result, "should have exactly 3 params total").to.have.lengthOf(3); }); + }); - it("should handle deep subdomains correctly", function () { - const url = "https://deep.sub.example.com/page?foo=bar"; - const expected = "https://deep.sub.example.com/page"; - const result1 = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"] - }); - const result2 = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["sub.example.com"] - }); - expect(result1, "should strip params for deep subdomains with domain matching").to.equal(expected); - expect(result2, "should strip params for deep subdomains with subdomain matching").to.equal(expected); + describe("with enableOrtb25Fields disabled", function () { + it("should not add IAB 1.0 filter params when disabled", function () { + const filters = { + ContentTier1: { limit: 3, threshold: 0.5 }, + ContentTier2: { limit: 5 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_1_threshold=0.5"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.not.include.match(/filter_1/); + expect(result).to.have.lengthOf(3); }); - it("should not match partial domain names", function () { - const url = "https://notexample.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"] - }); - expect(result, "should not match partial domain strings").to.equal(url); + it("should work correctly with all tier types when disabled", function () { + const filters = { + ContentTier1: { limit: 3 }, + ContentTier2: { limit: 5 }, + ContentTier3: { threshold: 0.7 }, + AudienceTier3: { limit: 2 } + }; + const contentSegtax = 6; + const result = neuwo.buildFilterQueryParams(filters, contentSegtax, false); + + expect(result).to.include("filter_6_1_limit=3"); + expect(result).to.include("filter_6_2_limit=5"); + expect(result).to.include("filter_6_3_threshold=0.7"); + expect(result).to.include("filter_4_3_limit=2"); + expect(result).to.not.include.match(/filter_1/); + expect(result).to.have.lengthOf(4); }); + }); + }); - it("should handle empty domain list", function () { - const url = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { stripQueryParamsForDomains: [] }); - expect(result, "should not strip params with empty domain list").to.equal(url); - }); + describe("extractCategoryIds", function () { + it("should extract IDs from single tier", function () { + const tierData = { + "1": [ + { id: "IAB12" }, + { id: "IAB12-3" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should extract all IDs from tier 1").to.deep.equal(["IAB12", "IAB12-3"]); }); - describe("when stripQueryParams is provided", function () { - it("should strip only specified query parameters", function () { - const url = "https://example.com/page?foo=bar&baz=qux&keep=this"; - const expected = "https://example.com/page?keep=this"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["foo", "baz"] + it("should extract IDs from multiple tiers", function () { + const tierData = { + "1": [ + { id: "IAB12" }, + { id: "IAB12-3" } + ], + "2": [ + { id: "IAB12-5" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should extract all IDs from all tiers").to.deep.equal(["IAB12", "IAB12-3", "IAB12-5"]); + }); + + it("should handle empty tier arrays", function () { + const tierData = { + "1": [], + "2": [ + { id: "IAB12" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should only extract from non-empty tiers").to.deep.equal(["IAB12"]); + }); + + it("should skip items without id property", function () { + const tierData = { + "1": [ + { id: "IAB12" }, + { name: "No ID" }, + { id: "IAB12-3" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should skip items without id").to.deep.equal(["IAB12", "IAB12-3"]); + }); + + it("should return empty array for null tierData", function () { + const result = neuwo.extractCategoryIds(null); + expect(result, "should return empty array for null").to.deep.equal([]); + }); + + it("should return empty array for undefined tierData", function () { + const result = neuwo.extractCategoryIds(undefined); + expect(result, "should return empty array for undefined").to.deep.equal([]); + }); + + it("should return empty array for empty object", function () { + const result = neuwo.extractCategoryIds({}); + expect(result, "should return empty array for empty object").to.deep.equal([]); + }); + + it("should handle non-array tier values", function () { + const tierData = { + "1": { id: "IAB12" }, // Not an array + "2": [ + { id: "IAB13" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should skip non-array values").to.deep.equal(["IAB13"]); + }); + + it("should handle null items in tier arrays", function () { + const tierData = { + "1": [ + { id: "IAB12" }, + null, + { id: "IAB12-3" } + ] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should skip null items").to.deep.equal(["IAB12", "IAB12-3"]); + }); + + it("should handle non-object tierData", function () { + expect(neuwo.extractCategoryIds("string"), "should handle string").to.deep.equal([]); + expect(neuwo.extractCategoryIds(123), "should handle number").to.deep.equal([]); + expect(neuwo.extractCategoryIds([]), "should handle array").to.deep.equal([]); + }); + + it("should extract from all tier numbers", function () { + const tierData = { + "1": [{ id: "IAB1" }], + "2": [{ id: "IAB2" }], + "3": [{ id: "IAB3" }], + "4": [{ id: "IAB4" }], + "5": [{ id: "IAB5" }] + }; + const result = neuwo.extractCategoryIds(tierData); + expect(result, "should extract from all tiers").to.deep.equal(["IAB1", "IAB2", "IAB3", "IAB4", "IAB5"]); + }); + }); + + describe("injectOrtbData", function () { + it("should correctly mutate the request bids config object with new data", function () { + const reqBidsConfigObj = { ortb2Fragments: { global: {} } }; + neuwo.injectOrtbData(reqBidsConfigObj, "c.d.e.f", { g: "h" }); + expect( + reqBidsConfigObj.ortb2Fragments.global.c.d.e.f.g, + "should deeply merge the new data into the target object" + ).to.equal("h"); + }); + }); + + describe("injectIabCategories", function () { + it("should not inject data when responseParsed is null or undefined", function () { + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfigCopy = JSON.parse(JSON.stringify(bidsConfig1)); + + neuwo.injectIabCategories(null, bidsConfig1, "2.2"); + neuwo.injectIabCategories(undefined, bidsConfig2, "2.2"); + + expect( + bidsConfig1.ortb2Fragments.global, + "should not modify ortb2Fragments when response is null" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + expect( + bidsConfig2.ortb2Fragments.global, + "should not modify ortb2Fragments when response is undefined" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + }); + + it("should not inject data when responseParsed is not an object", function () { + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const bidsConfigCopy = JSON.parse(JSON.stringify(bidsConfig1)); + + neuwo.injectIabCategories("invalid string", bidsConfig1, "2.2"); + neuwo.injectIabCategories(123, bidsConfig2, "2.2"); + neuwo.injectIabCategories([1, 2, 3], bidsConfig3, "2.2"); + + expect( + bidsConfig1.ortb2Fragments.global, + "should not modify ortb2Fragments when response is a string" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + expect( + bidsConfig2.ortb2Fragments.global, + "should not modify ortb2Fragments when response is a number" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + expect( + bidsConfig3.ortb2Fragments.global, + "should not modify ortb2Fragments when response is an array" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + }); + + it("should handle empty object response", function () { + const bidsConfig = bidsConfiglike(); + const bidsConfigCopy = JSON.parse(JSON.stringify(bidsConfig)); + + neuwo.injectIabCategories({}, bidsConfig, "2.2"); + + expect( + bidsConfig.ortb2Fragments.global, + "should not inject data when response object is empty" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + }); + + it("should inject content data when valid content segments exist", function () { + const response = { + "6": { + "1": [{ id: "52", name: "Food & Drink" }], + "2": [{ id: "90", name: "Cooking" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData, "should have content data").to.exist; + expect(contentData.ext.segtax, "should have correct segtax").to.equal(6); + expect(contentData.segment, "should have segments").to.have.lengthOf(2); + expect(contentData.segment[0].id, "first segment should match").to.equal("52"); + }); + + it("should inject audience data when valid audience segments exist", function () { + const response = { + "4": { + "3": [{ id: "49", name: "Female" }], + "4": [{ id: "431", name: "Age 25-34" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + expect(userData, "should have user data").to.exist; + expect(userData.ext.segtax, "should have correct segtax").to.equal(4); + expect(userData.segment, "should have segments").to.have.lengthOf(2); + expect(userData.segment[0].id, "first segment should match").to.equal("49"); + }); + + it("should inject both content and audience data when both exist", function () { + const response = { + "6": { + "1": [{ id: "52", name: "Food & Drink" }] + }, + "4": { + "3": [{ id: "49", name: "Female" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + + expect(contentData, "should have content data").to.exist; + expect(userData, "should have user data").to.exist; + expect(contentData.ext.segtax, "content should have segtax 6").to.equal(6); + expect(userData.ext.segtax, "audience should have segtax 4").to.equal(4); + }); + + it("should not inject empty audience data when only content segments exist", function () { + const response = { + "6": { + "1": [{ id: "52", name: "Food & Drink" }] + }, + "4": {} + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const userData = bidsConfig.ortb2Fragments.global?.user?.data; + expect(contentData, "should have content data").to.exist; + expect(userData, "should not inject empty audience data").to.be.undefined; + }); + + it("should not inject empty content data when only audience segments exist", function () { + const response = { + "6": {}, + "4": { + "3": [{ id: "49", name: "Female" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + expect(contentData, "should not inject empty content data").to.be.undefined; + expect(userData, "should have audience data").to.exist; + }); + + it("should handle different IAB Content Taxonomy versions", function () { + const response = { + "7": { + "1": [{ id: "80DV8O", name: "Automotive" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "3.0"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData, "should have content data").to.exist; + expect(contentData.ext.segtax, "should use segtax 7 for IAB 3.0").to.equal(7); + }); + + it("should not inject data when segtax has no segments", function () { + const response1 = { "6": {} }; + const response2 = { "4": {} }; + const response3 = { "6": { "1": [] }, "4": { "3": [] } }; + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + + neuwo.injectIabCategories(response1, bidsConfig1, "2.2"); + neuwo.injectIabCategories(response2, bidsConfig2, "2.2"); + neuwo.injectIabCategories(response3, bidsConfig3, "2.2"); + + expect(bidsConfig1.ortb2Fragments.global?.site?.content?.data, "should not inject empty content data").to.be.undefined; + expect(bidsConfig2.ortb2Fragments.global?.user?.data, "should not inject empty audience data").to.be.undefined; + expect(bidsConfig3.ortb2Fragments.global?.site?.content?.data, "should not inject content data with empty segments").to.be.undefined; + expect(bidsConfig3.ortb2Fragments.global?.user?.data, "should not inject audience data with empty segments").to.be.undefined; + }); + + it("should use default taxonomy version when invalid version provided", function () { + const response = { + "6": { + "1": [{ id: "52", name: "Food & Drink" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "invalid-version"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData, "should have content data").to.exist; + expect(contentData.ext.segtax, "should default to segtax 6 (IAB 2.2)").to.equal(6); + }); + + // OpenRTB 2.5 Category Fields Tests + describe("OpenRTB 2.5 category fields", function () { + describe("with enableOrtb25Fields enabled (default)", function () { + it("should inject category fields when IAB 1.0 data exists", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }], + "2": [{ id: "IAB12-3" }, { id: "IAB12-5" }] + }, + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + const siteSectioncat = bidsConfig.ortb2Fragments.global?.site?.sectioncat; + const sitePagecat = bidsConfig.ortb2Fragments.global?.site?.pagecat; + const contentCat = bidsConfig.ortb2Fragments.global?.site?.content?.cat; + + expect(siteCat, "should have site.cat").to.deep.equal(["IAB12", "IAB12-3", "IAB12-5"]); + expect(siteSectioncat, "should have site.sectioncat").to.deep.equal(["IAB12", "IAB12-3", "IAB12-5"]); + expect(sitePagecat, "should have site.pagecat").to.deep.equal(["IAB12", "IAB12-3", "IAB12-5"]); + expect(contentCat, "should have site.content.cat").to.deep.equal(["IAB12", "IAB12-3", "IAB12-5"]); }); - expect(result, "should remove only specified params").to.equal(expected); - }); - it("should handle single parameter stripping", function () { - const url = "https://example.com/page?remove=this&keep=that"; - const expected = "https://example.com/page?keep=that"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["remove"] + it("should inject category fields with single IAB 1.0 segment", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should have single category").to.deep.equal(["IAB12"]); }); - expect(result, "should remove single specified param").to.equal(expected); - }); - it("should return URL without query string if all params are stripped", function () { - const url = "https://example.com/page?foo=bar&baz=qux"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["foo", "baz"] + it("should not inject category fields when IAB 1.0 data is missing", function () { + const response = { + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + const siteSectioncat = bidsConfig.ortb2Fragments.global?.site?.sectioncat; + + expect(siteCat, "should not have site.cat").to.be.undefined; + expect(siteSectioncat, "should not have site.sectioncat").to.be.undefined; + }); + + it("should not inject category fields when IAB 1.0 data is empty", function () { + const response = { + "1": {}, + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should not have site.cat with empty IAB 1.0").to.be.undefined; + }); + + it("should not inject category fields when IAB 1.0 tiers are empty arrays", function () { + const response = { + "1": { + "1": [], + "2": [] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should not have site.cat with empty tier arrays").to.be.undefined; + }); + + it("should handle IAB 1.0 data with malformed items", function () { + const response = { + "1": { + "1": [ + { id: "IAB12" }, + { name: "No ID" }, + null, + { id: "IAB12-3" } + ] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should skip malformed items").to.deep.equal(["IAB12", "IAB12-3"]); + }); + + it("should inject both content data and category fields", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }] + }, + "6": { + "1": [{ id: "52", name: "Food & Drink" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + + expect(contentData, "should have content data").to.exist; + expect(contentData.ext.segtax, "should have segtax 6").to.equal(6); + expect(siteCat, "should have category fields").to.deep.equal(["IAB12"]); + }); + + it("should merge category fields with existing data", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }] + } + }; + const bidsConfig = bidsConfiglike(); + // Pre-populate with existing category data + bidsConfig.ortb2Fragments.global = { + site: { + cat: ["EXISTING1"] + } + }; + + neuwo.injectIabCategories(response, bidsConfig, "2.2"); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + // mergeDeep should deduplicate and merge arrays + expect(siteCat, "should merge with existing data").to.include("IAB12"); + expect(siteCat, "should preserve existing data").to.include("EXISTING1"); }); - expect(result, "should remove query string when all params stripped").to.equal(expected); }); - it("should handle case where specified params do not exist", function () { - const url = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["nonexistent", "alsonothere"] + describe("with enableOrtb25Fields disabled", function () { + it("should not inject category fields when disabled", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }], + "2": [{ id: "IAB12-3" }] + }, + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2", false); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + const siteSectioncat = bidsConfig.ortb2Fragments.global?.site?.sectioncat; + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + + expect(siteCat, "should not have site.cat").to.be.undefined; + expect(siteSectioncat, "should not have site.sectioncat").to.be.undefined; + expect(contentData, "should still have content data (segtax 6)").to.exist; }); - expect(result, "should handle non-existent params gracefully").to.equal(url); + + it("should inject content data but not category fields when disabled", function () { + const response = { + "1": { + "1": [{ id: "IAB12" }] + }, + "6": { + "1": [{ id: "52", name: "Food & Drink" }] + } + }; + const bidsConfig = bidsConfiglike(); + + neuwo.injectIabCategories(response, bidsConfig, "2.2", false); + + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + + expect(contentData, "should have content data").to.exist; + expect(contentData.ext.segtax).to.equal(6); + expect(siteCat, "should not have category fields").to.be.undefined; + }); + }); + }); + }); + + describe("getBidRequestData", function () { + it("should call callback and not make API request when no URL is available", function () { + const getRefererInfoStub = sinon.stub(refererDetection, "getRefererInfo").returns({ page: "" }); + const bidsConfig = bidsConfiglike(); + const conf = config(); + let callbackCalled = false; + + neuwo.getBidRequestData(bidsConfig, () => { callbackCalled = true; }, conf, "consent data"); + + expect(callbackCalled, "callback should be called for empty URL").to.be.true; + expect(server.requests.length, "should not make API request for empty URL").to.equal(0); + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "should not inject any data").to.be.undefined; + + getRefererInfoStub.restore(); + }); + + it("should call callback when response processing throws an error", function (done) { + const bidsConfig = { ortb2Fragments: null }; + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/processing-error"; + + neuwo.getBidRequestData(bidsConfig, () => { + const contentData = bidsConfig.ortb2Fragments?.global?.site?.content?.data; + expect(contentData, "should not inject data after processing error").to.be.undefined; + done(); + }, conf, "consent data"); + + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(getNeuwoApiResponse()) + ); + }); + + describe("when using IAB Content Taxonomy 2.2 (API default)", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig = bidsConfiglike(); + const conf = config(); + // control xhr api request target for testing + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + expect(request.url, "The request URL should include the product identifier").to.include( + "_neuwo_prod=PrebidModule" + ); + expect(request.url, "API should include iabVersions parameter for segtax 6").to.include( + "iabVersions=6" + ); + expect(request.url, "API should include iabVersions parameter for segtax 4").to.include( + "iabVersions=4" + ); + expect(request.method, "API should use GET method").to.equal("GET"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; + expect(contentData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + contentData.ext.segtax, + "The segtax value should correspond to IAB Content Taxonomy 2.2" + ).to.equal(6); + expect( + contentData.segment[0].id, + "The first segment ID should match the API response" + ).to.equal(apiResponse["6"]["1"][0].id); + expect( + contentData.segment[1].id, + "The second segment ID should match the API response" + ).to.equal(apiResponse["6"]["2"][0].id); + }); + }); + + describe("when using IAB Content Taxonomy 1.0", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = { + 1: { 1: [{ id: "IAB1" }], 2: [{ id: "IAB1-1" }], 3: [{ id: "IAB1-1-1" }] }, + 4: { 3: [{ id: "49" }, { id: "780" }], 4: [{ id: "431" }], 5: [{ id: "98" }] }, + }; + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.iabContentTaxonomyVersion = "1.0"; + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + expect(request.url, "The request URL should include the product identifier").to.include( + "_neuwo_prod=PrebidModule" + ); + expect(request.url, "API should include iabVersions parameter for segtax 1").to.include( + "iabVersions=1" + ); + expect(request.url, "API should include iabVersions parameter for segtax 4").to.include( + "iabVersions=4" + ); + expect(request.method, "API should use GET method").to.equal("GET"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; + expect(contentData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + contentData.ext.segtax, + "The segtax value should correspond to IAB Content Taxonomy 1.0" + ).to.equal(1); + expect( + contentData.segment[0].id, + "The first segment ID should match the API response" + ).to.equal(apiResponse["1"]["1"][0].id); + expect( + contentData.segment[1].id, + "The second segment ID should match the API response" + ).to.equal(apiResponse["1"]["2"][0].id); + }); + }); + + describe("when using IAB Content Taxonomy 3.0", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = { + 7: { 1: [{ id: "80DV8O" }], 2: [{ id: "90" }], 3: [{ id: "106" }] }, + 4: { 3: [{ id: "49" }, { id: "780" }], 4: [{ id: "431" }], 5: [{ id: "98" }] }, + }; + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.iabContentTaxonomyVersion = "3.0"; + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + expect(request.url, "The request URL should include the product identifier").to.include( + "_neuwo_prod=PrebidModule" + ); + expect(request.url, "API should include iabVersions parameter for segtax 7").to.include( + "iabVersions=7" + ); + expect(request.url, "API should include iabVersions parameter for segtax 4").to.include( + "iabVersions=4" + ); + expect(request.method, "API should use GET method").to.equal("GET"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; + expect(contentData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + contentData.ext.segtax, + "The segtax value should correspond to IAB Content Taxonomy 3.0" + ).to.equal(7); + expect( + contentData.segment[0].id, + "The first segment ID should match the API response" + ).to.equal(apiResponse["7"]["1"][0].id); + expect( + contentData.segment[1].id, + "The second segment ID should match the API response" + ).to.equal(apiResponse["7"]["2"][0].id); + }); + }); + + describe("when using IAB Audience Taxonomy 1.1", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig = bidsConfiglike(); + const conf = config(); + // control xhr api request target for testing + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + expect(request.method, "API should use GET method").to.equal("GET"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + const userData = bidsConfig.ortb2Fragments.global.user.data[0]; + expect(userData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + userData.ext.segtax, + "The segtax value should correspond to IAB Audience Taxonomy 1.1" + ).to.equal(4); + expect( + userData.segment[0].id, + "The first segment ID should match the API response (tier 3, first item)" + ).to.equal(apiResponse["4"]["3"][0].id); + expect( + userData.segment[1].id, + "The second segment ID should match the API response (tier 3, second item)" + ).to.equal(apiResponse["4"]["3"][1].id); + }); + }); + + it("should not change the bids object structure after an unsuccessful API response", function () { + const bidsConfig = bidsConfiglike(); + const bidsConfigCopy = bidsConfiglike(); + const conf = config(); + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 404, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify({ detail: "test error" }) + ); + expect( + bidsConfig, + "The bids config object should remain unmodified after a failed API call" + ).to.deep.equal(bidsConfigCopy); + }); + + // OpenRTB 2.5 Feature Tests + describe("OpenRTB 2.5 category fields", function () { + describe("with enableOrtb25Fields enabled (default)", function () { + it("should include iabVersions=1 parameter in API request", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "should include iabVersions=1").to.include("iabVersions=1"); + expect(request.url, "should include iabVersions=6").to.include("iabVersions=6"); + expect(request.url, "should include iabVersions=4").to.include("iabVersions=4"); + }); + + it("should not duplicate iabVersions=1 when iabContentTaxonomyVersion is 1.0", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + conf.params.iabContentTaxonomyVersion = "1.0"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + const matches = request.url.match(/iabVersions=1(?!\d)/g) || []; + expect(matches.length, "iabVersions=1 should appear exactly once").to.equal(1); + expect(request.url, "should still include iabVersions=4").to.include("iabVersions=4"); + }); + + it("should inject category fields when API returns IAB 1.0 data", function () { + const apiResponse = { + "1": { + "1": [{ id: "IAB12" }], + "2": [{ id: "IAB12-3" }] + }, + "6": { + "1": [{ id: "52" }] + }, + "4": { + "3": [{ id: "49" }] + } + }; + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + + expect(siteCat, "should have site.cat").to.deep.equal(["IAB12", "IAB12-3"]); + expect(contentData, "should have content data").to.exist; + }); + + it("should send IAB 1.0 filter configuration in URL parameters", function () { + const apiResponse = { + "1": { + "1": [{ id: "IAB12" }], + "2": [{ id: "IAB12-3" }] + }, + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + conf.params.iabTaxonomyFilters = { + ContentTier1: { limit: 2 } + }; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + + const request = server.requests[0]; + expect(request.url, "should have filter for segtax 1 tier 1").to.include("filter_1_1_limit=2"); + expect(request.url, "should have filter for segtax 6 tier 1").to.include("filter_6_1_limit=2"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should inject category fields").to.deep.equal(["IAB12", "IAB12-3"]); + }); + }); + + describe("with enableOrtb25Fields disabled", function () { + it("should not include iabVersions=1 parameter in API request", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + conf.params.enableOrtb25Fields = false; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "should not include iabVersions=1").to.not.include("iabVersions=1"); + expect(request.url, "should still include iabVersions=6").to.include("iabVersions=6"); + }); + + it("should not inject category fields even if API returns IAB 1.0 data", function () { + const apiResponse = { + "1": { + "1": [{ id: "IAB12" }] + }, + "6": { + "1": [{ id: "52" }] + } + }; + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + conf.params.enableOrtb25Fields = false; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + + expect(siteCat, "should not have site.cat").to.be.undefined; + expect(contentData, "should still have content data").to.exist; + }); + + it("should not send IAB 1.0 filters in URL parameters", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + conf.params.enableOrtb25Fields = false; + conf.params.iabTaxonomyFilters = { + ContentTier1: { limit: 3 }, + ContentTier2: { limit: 5 } + }; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "should not have segtax 1 filters").to.not.match(/filter_1_/); + expect(request.url, "should have segtax 6 filters").to.include("filter_6_1_limit=3"); + expect(request.url, "should have segtax 6 tier 2 filters").to.include("filter_6_2_limit=5"); + }); + }); + }); + }); + + describe("cleanUrl", function () { + describe("when no stripping options are provided", function () { + it("should return the URL unchanged", function () { + const url = "https://example.com/page?foo=bar&baz=qux"; + const result = neuwo.cleanUrl(url, {}); + expect(result, "should return the original URL with all query params intact").to.equal(url); + }); + + it("should return the URL unchanged when options object is empty", function () { + const url = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url); + expect(result, "should handle missing options parameter").to.equal(url); + }); + }); + + describe("with query parameters edge cases", function () { + it("should strip all query parameters from the URL for `stripAllQueryParams` (edge cases)", function () { + const stripAll = (url) => neuwo.cleanUrl(url, { stripAllQueryParams: true }); + const expected = "https://example.com/page"; + const expectedWithFragment = "https://example.com/page#anchor"; + + // Basic formats + expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); + expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); + expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); + expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); + + // Multiple parameters + expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); + expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + + // Special characters and encoding + expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); + expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); + expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + + // Delimiters and syntax edge cases + expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); + expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + + // Empty and missing cases + expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); + expect(stripAll("https://example.com/page??"), "should remove double question mark").to.equal(expected); + expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + + // Unicode and special values + expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); + expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); + expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + + // Fragment positioning (fragments are preserved by default) + expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); + expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); + }); + + it("should strip all query parameters from the URL for `stripQueryParamsForDomains` (edge cases)", function () { + const stripAll = (url) => neuwo.cleanUrl(url, { stripQueryParamsForDomains: ["example.com"] }); + const expected = "https://example.com/page"; + const expectedWithFragment = "https://example.com/page#anchor"; + + // Basic formats + expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); + expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); + expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); + expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); + + // Multiple parameters + expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); + expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + + // Special characters and encoding + expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); + expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); + expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + + // Delimiters and syntax edge cases + expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); + expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + + // Empty and missing cases + expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); + expect(stripAll("https://example.com/page??"), "should remove double question mark").to.equal(expected); + expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + + // Unicode and special values + expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); + expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); + expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + + // Fragment positioning (fragments are preserved by default) + expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); + expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); + }); + + it("should strip all query parameters from the URL for `stripQueryParams` (edge cases)", function () { + const stripAll = (url) => neuwo.cleanUrl(url, { stripQueryParams: ["key", "key1", "key2", "", "?"] }); + const expected = "https://example.com/page"; + const expectedWithFragment = "https://example.com/page#anchor"; + + // Basic formats + expect(stripAll("https://example.com/page?key=value"), "should remove basic key=value params").to.equal(expected); + expect(stripAll("https://example.com/page?key="), "should remove params with empty value").to.equal(expected); + expect(stripAll("https://example.com/page?key"), "should remove params without equals sign").to.equal(expected); + expect(stripAll("https://example.com/page?=value"), "should remove params with empty key").to.equal(expected); + + // Multiple parameters + expect(stripAll("https://example.com/page?key1=value1&key2=value2"), "should remove multiple different params").to.equal(expected); + expect(stripAll("https://example.com/page?key=value1&key=value2"), "should remove multiple params with same key").to.equal(expected); + + // Special characters and encoding + expect(stripAll("https://example.com/page?key=value%20with%20spaces"), "should remove URL encoded spaces").to.equal(expected); + expect(stripAll("https://example.com/page?key=value+with+plus"), "should remove plus as space").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%3D%26%3F"), "should remove encoded special chars").to.equal(expected); + expect(stripAll("https://example.com/page?key=%"), "should remove incomplete encoding").to.equal(expected); + expect(stripAll("https://example.com/page?key=value%2"), "should remove malformed encoding").to.equal(expected); + + // Delimiters and syntax edge cases + expect(stripAll("https://example.com/page?&key=value"), "should remove params with leading ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&"), "should remove params with trailing ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value&&key2=value2"), "should remove params with double ampersand").to.equal(expected); + expect(stripAll("https://example.com/page?key=value?key2=value2"), "should remove params with question mark delimiter").to.equal(expected); + expect(stripAll("https://example.com/page?key=value;key2=value2"), "should remove params with semicolon delimiter").to.equal(expected); + + // Empty and missing cases + expect(stripAll("https://example.com/page?"), "should remove question mark alone").to.equal(expected); + expect(stripAll("https://example.com/page"), "should handle URL without query string").to.equal(expected); + + // Unicode and special values + expect(stripAll("https://example.com/page?key=值"), "should remove unicode characters").to.equal(expected); + expect(stripAll("https://example.com/page?key=null"), "should remove string 'null'").to.equal(expected); + expect(stripAll("https://example.com/page?key=undefined"), "should remove string 'undefined'").to.equal(expected); + + // Fragment positioning (fragments are preserved by default) + expect(stripAll("https://example.com/page?key=value#anchor"), "should remove query params and preserve fragment").to.equal(expectedWithFragment); + expect(stripAll("https://example.com/page#anchor?key=value"), "should preserve fragment before params").to.equal("https://example.com/page#anchor?key=value"); + }); + }); + + describe("when stripAllQueryParams is true", function () { + it("should strip all query parameters from the URL", function () { + const url = "https://example.com/page?foo=bar&baz=qux&test=123"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); + expect(result, "should remove all query parameters").to.equal(expected); + }); + + it("should return the URL unchanged if there are no query parameters", function () { + const url = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); + expect(result, "should handle URLs without query params").to.equal(url); + }); + + it("should preserve the hash fragment when stripping query params without stripFragments", function () { + const url = "https://example.com/page?foo=bar#section"; + const expected = "https://example.com/page#section"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); + expect(result, "should preserve hash fragments by default").to.equal(expected); + }); + + it("should strip hash fragment when stripFragments is enabled", function () { + const url = "https://example.com/page?foo=bar#section"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true, stripFragments: true }); + expect(result, "should strip both query params and fragments").to.equal(expected); + }); + + it("should strip query params but preserve path and protocol", function () { + const url = "https://subdomain.example.com:8080/path/to/page?param=value"; + const expected = "https://subdomain.example.com:8080/path/to/page"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true }); + expect(result, "should preserve protocol, domain, port, and path").to.equal(expected); + }); + }); + + describe("when stripQueryParamsForDomains is provided", function () { + it("should strip all query params for exact domain match", function () { + const url = "https://example.com/page?foo=bar&baz=qux"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"] + }); + expect(result, "should strip params for exact domain match").to.equal(expected); + }); + + it("should strip all query params for subdomain match", function () { + const url = "https://sub.example.com/page?foo=bar"; + const expected = "https://sub.example.com/page"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"] + }); + expect(result, "should strip params for subdomains").to.equal(expected); + }); + + it("should not strip query params if domain does not match", function () { + const url = "https://other.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"] + }); + expect(result, "should preserve params for non-matching domains").to.equal(url); + }); + + it("should not strip query params if subdomain is provided for domain", function () { + const url = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["sub.example.com"] + }); + expect(result, "should preserve params for domain when subdomain is provided").to.equal(url); + }); + + it("should handle multiple domains in the list", function () { + const url1 = "https://example.com/page?foo=bar"; + const url2 = "https://test.com/page?foo=bar"; + const url3 = "https://other.com/page?foo=bar"; + const domains = ["example.com", "test.com"]; + + const result1 = neuwo.cleanUrl(url1, { stripQueryParamsForDomains: domains }); + const result2 = neuwo.cleanUrl(url2, { stripQueryParamsForDomains: domains }); + const result3 = neuwo.cleanUrl(url3, { stripQueryParamsForDomains: domains }); + + expect(result1, "should strip params for first domain").to.equal("https://example.com/page"); + expect(result2, "should strip params for second domain").to.equal("https://test.com/page"); + expect(result3, "should preserve params for non-listed domain").to.equal(url3); + }); + + it("should handle deep subdomains correctly", function () { + const url = "https://deep.sub.example.com/page?foo=bar"; + const expected = "https://deep.sub.example.com/page"; + const result1 = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"] + }); + const result2 = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["sub.example.com"] + }); + expect(result1, "should strip params for deep subdomains with domain matching").to.equal(expected); + expect(result2, "should strip params for deep subdomains with subdomain matching").to.equal(expected); + }); + + it("should not match partial domain names", function () { + const url = "https://notexample.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"] + }); + expect(result, "should not match partial domain strings").to.equal(url); + }); + + it("should handle empty domain list", function () { + const url = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { stripQueryParamsForDomains: [] }); + expect(result, "should not strip params with empty domain list").to.equal(url); + }); + }); + + describe("when stripQueryParams is provided", function () { + it("should strip only specified query parameters", function () { + const url = "https://example.com/page?foo=bar&baz=qux&keep=this"; + const expected = "https://example.com/page?keep=this"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["foo", "baz"] + }); + expect(result, "should remove only specified params").to.equal(expected); + }); + + it("should handle single parameter stripping", function () { + const url = "https://example.com/page?remove=this&keep=that"; + const expected = "https://example.com/page?keep=that"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["remove"] + }); + expect(result, "should remove single specified param").to.equal(expected); + }); + + it("should return URL without query string if all params are stripped", function () { + const url = "https://example.com/page?foo=bar&baz=qux"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["foo", "baz"] + }); + expect(result, "should remove query string when all params stripped").to.equal(expected); + }); + + it("should handle case where specified params do not exist", function () { + const url = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["nonexistent", "alsonothere"] + }); + expect(result, "should handle non-existent params gracefully").to.equal(url); + }); + + it("should handle empty param list", function () { + const url = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { stripQueryParams: [] }); + expect(result, "should not strip params with empty list").to.equal(url); + }); + + it("should preserve param order for remaining params", function () { + const url = "https://example.com/page?a=1&b=2&c=3&d=4"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["b", "d"] + }); + expect(result, "should preserve order of remaining params").to.include("a=1"); + expect(result, "should preserve order of remaining params").to.include("c=3"); + expect(result, "should not include stripped param b").to.not.include("b=2"); + expect(result, "should not include stripped param d").to.not.include("d=4"); + }); + }); + + describe("error handling", function () { + it("should return null or undefined input unchanged", function () { + expect(neuwo.cleanUrl(null, {}), "should handle null input").to.equal(null); + expect(neuwo.cleanUrl(undefined, {}), "should handle undefined input").to.equal(undefined); + expect(neuwo.cleanUrl("", {}), "should handle empty string").to.equal(""); + }); + + it("should return invalid URL unchanged and log error", function () { + const invalidUrl = "not-a-valid-url"; + const result = neuwo.cleanUrl(invalidUrl, { stripAllQueryParams: true }); + expect(result, "should return invalid URL unchanged").to.equal(invalidUrl); + }); + + it("should handle malformed URLs gracefully", function () { + const malformedUrl = "http://"; + const result = neuwo.cleanUrl(malformedUrl, { stripAllQueryParams: true }); + expect(result, "should return malformed URL unchanged").to.equal(malformedUrl); + }); + }); + + describe("when stripFragments is enabled", function () { + it("should strip URL fragments from URLs without query params", function () { + const url = "https://example.com/page#section"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripFragments: true }); + expect(result, "should remove hash fragment").to.equal(expected); + }); + + it("should strip URL fragments from URLs with query params", function () { + const url = "https://example.com/page?foo=bar#section"; + const expected = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { stripFragments: true }); + expect(result, "should remove hash fragment and preserve query params").to.equal(expected); + }); + + it("should strip fragments when combined with stripAllQueryParams", function () { + const url = "https://example.com/page?foo=bar#section"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripAllQueryParams: true, stripFragments: true }); + expect(result, "should remove both query params and fragment").to.equal(expected); + }); + + it("should strip fragments when combined with stripQueryParamsForDomains", function () { + const url = "https://example.com/page?foo=bar#section"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"], + stripFragments: true + }); + expect(result, "should remove both query params and fragment for matching domain").to.equal(expected); + }); + + it("should strip fragments when combined with stripQueryParams", function () { + const url = "https://example.com/page?foo=bar&keep=this#section"; + const expected = "https://example.com/page?keep=this"; + const result = neuwo.cleanUrl(url, { + stripQueryParams: ["foo"], + stripFragments: true + }); + expect(result, "should remove specified query params and fragment").to.equal(expected); + }); + + it("should handle URLs without fragments gracefully", function () { + const url = "https://example.com/page?foo=bar"; + const expected = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { stripFragments: true }); + expect(result, "should handle URLs without fragments").to.equal(expected); + }); + + it("should handle empty fragments", function () { + const url = "https://example.com/page#"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { stripFragments: true }); + expect(result, "should remove empty fragment").to.equal(expected); + }); + + it("should handle complex fragments with special characters", function () { + const url = "https://example.com/page?foo=bar#section-1/subsection?query"; + const expected = "https://example.com/page?foo=bar"; + const result = neuwo.cleanUrl(url, { stripFragments: true }); + expect(result, "should remove complex fragments").to.equal(expected); + }); + }); + + describe("option priority", function () { + it("should apply stripAllQueryParams first when multiple options are set", function () { + const url = "https://example.com/page?foo=bar&baz=qux"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { + stripAllQueryParams: true, + stripQueryParams: ["foo"] + }); + expect(result, "stripAllQueryParams should take precedence").to.equal(expected); + }); + + it("should apply stripQueryParamsForDomains before stripQueryParams", function () { + const url = "https://example.com/page?foo=bar&baz=qux"; + const expected = "https://example.com/page"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"], + stripQueryParams: ["foo"] + }); + expect(result, "domain-specific stripping should take precedence").to.equal(expected); + }); + + it("should not strip for non-matching domain even with stripQueryParams set", function () { + const url = "https://other.com/page?foo=bar&baz=qux"; + const expected = "https://other.com/page?baz=qux"; + const result = neuwo.cleanUrl(url, { + stripQueryParamsForDomains: ["example.com"], + stripQueryParams: ["foo"] + }); + expect(result, "should fall through to stripQueryParams for non-matching domain").to.equal(expected); + }); + }); + }); + + // Integration Tests + describe("injectIabCategories edge cases and merging", function () { + it("should not inject data if response contains no segments", function () { + const apiResponse = { "6": {}, "4": {} }; // Empty response (no segments) + const bidsConfig = bidsConfiglike(); + const bidsConfigCopy = bidsConfiglike(); + const conf = config(); + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // After a successful response with no segments, the global ortb2 fragments should remain empty + // as the data injection logic only injects when segments exist + expect( + bidsConfig.ortb2Fragments.global, + "The global ORTB fragments should remain empty" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + }); + + it("should append content and user data to existing ORTB fragments", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig = bidsConfiglike(); + // Simulate existing first-party data from another source/module + const existingContentData = { name: "other_content_provider", segment: [{ id: "1" }] }; + const existingUserData = { name: "other_user_provider", segment: [{ id: "2" }] }; + + bidsConfig.ortb2Fragments.global = { + site: { + content: { + data: [existingContentData], + }, + }, + user: { + data: [existingUserData], + }, + }; + const conf = config(); + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const siteData = bidsConfig.ortb2Fragments.global.site.content.data; + const userData = bidsConfig.ortb2Fragments.global.user.data; + + // Check that the existing data is still there (index 0) + expect(siteData[0], "Existing site.content.data should be preserved").to.deep.equal( + existingContentData + ); + expect(userData[0], "Existing user.data should be preserved").to.deep.equal(existingUserData); + + // Check that the new Neuwo data is appended (index 1) + expect(siteData.length, "site.content.data array should have 2 entries").to.equal(2); + expect(userData.length, "user.data array should have 2 entries").to.equal(2); + expect(siteData[1].name, "The appended content data should be from Neuwo").to.equal( + neuwo.DATA_PROVIDER + ); + expect(userData[1].name, "The appended user data should be from Neuwo").to.equal( + neuwo.DATA_PROVIDER + ); + }); + + it("should correctly construct API URL when neuwoApiUrl already contains query parameters", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig = bidsConfiglike(); + const conf = config(); + // Set API URL that already has query parameters + conf.params.neuwoApiUrl = "https://edge.neuwo.ai/api/aitopics/edge/v1/iab?environment=production"; + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + // Should use & as joiner instead of ? + expect(request.url, "URL should contain environment param from base URL").to.include("environment=production"); + expect(request.url, "URL should contain token param joined with &").to.include("&token="); + expect(request.url, "URL should contain url param").to.include("&url="); + expect(request.url, "URL should contain product identifier").to.include("&_neuwo_prod=PrebidModule"); + expect(request.url, "URL should include iabVersions parameter").to.include("iabVersions="); + // Should not have ?? in the URL + expect(request.url, "URL should not contain double question marks").to.not.include("??"); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; + expect(contentData.name, "Should successfully process response").to.equal(neuwo.DATA_PROVIDER); + }); + + it("should treat a legacy URL with /v1/iab in query params as a legacy endpoint", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + // Proxy URL where /v1/iab appears in query params, not the path + conf.params.neuwoApiUrl = "https://proxy.example.com/api?redirect=/v1/iab"; + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + // Legacy endpoints should NOT include iabVersions params + expect(request.url, "should not include iabVersions for legacy endpoint").to.not.include("iabVersions="); + // Should still include token and url params + expect(request.url, "should include token param").to.include("token="); + expect(request.url, "should include url param").to.include("url="); + }); + + it("should detect /v1/iab endpoint from a malformed URL using fallback parsing", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + // Malformed URL that causes new URL() to throw, but has /v1/iab in path + conf.params.neuwoApiUrl = "/v1/iab"; + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + // Fallback parser should detect /v1/iab in path portion and treat as IAB endpoint + expect(request.url, "should include iabVersions for IAB endpoint").to.include("iabVersions="); + }); + }); + + describe("getBidRequestData with caching", function () { + describe("when enableCache is true (default)", function () { + it("should cache the API response and reuse it on subsequent calls", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=1"; + + // First call should make an API request + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + const request1 = server.requests[0]; + request1.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call should use cached response (no new API request) + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Second call should not make a new API request").to.equal(1); + + // Both configs should have identical data (second served from cache) + const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; + expect(contentData1, "First config should have Neuwo data").to.exist; + expect(contentData2, "Second config should have Neuwo data from cache").to.exist; + expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData1.segment, "Cached data should have same segments as original").to.deep.equal(contentData2.segment); + }); + + it("should cache when enableCache is explicitly set to true", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=2"; + conf.params.enableCache = true; + + // First call + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + const request1 = server.requests[0]; + request1.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call should use cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Second call should use cached response").to.equal(1); + }); + + it("should handle concurrent requests by sharing a pending request promise", function (done) { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=concurrent"; + conf.params.enableCache = true; + + let callbackCount = 0; + const callback = () => { + callbackCount++; + if (callbackCount === 3) { + // All callbacks have been called, now verify the data + try { + const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; + const contentData3 = bidsConfig3.ortb2Fragments.global.site.content.data[0]; + + expect(contentData1, "First config should have Neuwo data").to.exist; + expect(contentData2, "Second config should have Neuwo data from pending request").to.exist; + expect(contentData3, "Third config should have Neuwo data from pending request").to.exist; + expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData3.name, "Third config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + done(); + } catch (e) { + done(e); + } + } + }; + + // Make three concurrent calls before responding to the first request + neuwo.getBidRequestData(bidsConfig1, callback, conf, "consent data"); + neuwo.getBidRequestData(bidsConfig2, callback, conf, "consent data"); + neuwo.getBidRequestData(bidsConfig3, callback, conf, "consent data"); + + // Only one API request should be made + expect(server.requests.length, "Only one API request should be made for concurrent calls").to.equal(1); + + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + }); + + it("should transition through all three cache states: pending request, then cached response", function (done) { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=three-stage"; + conf.params.enableCache = true; + + let callback1and2Count = 0; + + const callback1and2 = () => { + callback1and2Count++; + if (callback1and2Count === 2) { + // Both first and second callbacks have been called + // Stage 3: Third request should use cached response (not pending request) + neuwo.getBidRequestData(bidsConfig3, () => { + try { + expect(server.requests.length, "Third call should use cache and not make a new API request").to.equal(1); + + // All three configs should have the same data + const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; + const contentData3 = bidsConfig3.ortb2Fragments.global.site.content.data[0]; + + expect(contentData1, "First config should have Neuwo data").to.exist; + expect(contentData2, "Second config should have Neuwo data from pending request").to.exist; + expect(contentData3, "Third config should have Neuwo data from cache").to.exist; + expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData3.name, "Third config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + done(); + } catch (e) { + done(e); + } + }, conf, "consent data"); + } + }; + + // Stage 1: First request initiates API call (creates pending request) + neuwo.getBidRequestData(bidsConfig1, callback1and2, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + // Stage 2: Second request should attach to pending request before response + neuwo.getBidRequestData(bidsConfig2, callback1and2, conf, "consent data"); + expect(server.requests.length, "Second call should not make a new API request").to.equal(1); + + // Respond to the API request, which populates the cache + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + }); + + it("should not share cache between requests with different parameters", function (done) { + const apiResponse1 = getNeuwoApiResponse(); + const apiResponse2 = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf1 = config(); + conf1.params.websiteToAnalyseUrl = "https://publisher.works/page-a"; + conf1.params.enableCache = true; + const conf2 = config(); + conf2.params.websiteToAnalyseUrl = "https://publisher.works/page-b"; + conf2.params.enableCache = true; + + let callbackCount = 0; + const callback = () => { + callbackCount++; + if (callbackCount === 2) { + try { + // Both should have made separate API requests + expect(server.requests.length, "Should make two separate API requests for different URLs").to.equal(2); + expect(server.requests[0].url).to.contain("page-a"); + expect(server.requests[1].url).to.contain("page-b"); + done(); + } catch (e) { + done(e); + } + } + }; + + // Two concurrent calls with different URLs + neuwo.getBidRequestData(bidsConfig1, callback, conf1, "consent data"); + neuwo.getBidRequestData(bidsConfig2, callback, conf2, "consent data"); + + expect(server.requests.length, "Should make two separate API requests").to.equal(2); + + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse1) + ); + server.requests[1].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse2) + ); + }); + + it("should use cache for same URL but make new request after config change", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-a"; + conf.params.enableCache = true; + + // First call + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length).to.equal(1); + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call with same URL - should use cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Same URL should use cache").to.equal(1); + + // Third call with different URL (simulating config change) - should make new request + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-b"; + neuwo.getBidRequestData(bidsConfig3, () => {}, conf, "consent data"); + expect(server.requests.length, "Different URL should make new request").to.equal(2); + expect(server.requests[1].url).to.contain("page-b"); + }); + + it("should not share cache when iabContentTaxonomyVersion changes", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf.params.enableCache = true; + conf.params.iabContentTaxonomyVersion = "2.2"; + + // First call with taxonomy 2.2 + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length).to.equal(1); + expect(server.requests[0].url).to.contain("iabVersions=6"); // segtax 6 = taxonomy 2.2 + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call with same taxonomy - should use cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Same taxonomy version should use cache").to.equal(1); + + // Third call with different taxonomy version - should make new request + conf.params.iabContentTaxonomyVersion = "3.0"; + neuwo.getBidRequestData(bidsConfig3, () => {}, conf, "consent data"); + expect(server.requests.length, "Different taxonomy version should make new request").to.equal(2); + expect(server.requests[1].url).to.contain("iabVersions=7"); // segtax 7 = taxonomy 3.0 + }); + + it("should evict the oldest cache entry when MAX_CACHE_ENTRIES is exceeded", async function () { + const apiResponse = getNeuwoApiResponse(); + const conf = config(); + conf.params.enableCache = true; + + // Fill cache with 10 entries (MAX_CACHE_ENTRIES) + for (let i = 0; i < 10; i++) { + const bidsConfig = bidsConfiglike(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-" + i; + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + server.requests[i].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + } + // Flush microtasks so pendingRequests are cleaned up via .finally() handlers + await Promise.resolve(); + + expect(server.requests.length, "Should have made 10 API requests").to.equal(10); + + // Verify page-0 is cached + const bidsConfigCached = bidsConfiglike(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-0"; + neuwo.getBidRequestData(bidsConfigCached, () => {}, conf, "consent data"); + expect(server.requests.length, "page-0 should be served from cache").to.equal(10); + + // Add 11th entry to trigger eviction of the oldest (page-0) + const bidsConfig11 = bidsConfiglike(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-10"; + neuwo.getBidRequestData(bidsConfig11, () => {}, conf, "consent data"); + expect(server.requests.length, "page-10 should trigger new request").to.equal(11); + server.requests[10].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + await Promise.resolve(); + + // page-0 should have been evicted and require a new request + const bidsConfigEvicted = bidsConfiglike(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-0"; + neuwo.getBidRequestData(bidsConfigEvicted, () => {}, conf, "consent data"); + expect(server.requests.length, "page-0 should be evicted and trigger new request").to.equal(12); + + // page-1 should still be cached + const bidsConfigStillCached = bidsConfiglike(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/page-1"; + neuwo.getBidRequestData(bidsConfigStillCached, () => {}, conf, "consent data"); + expect(server.requests.length, "page-1 should still be in cache").to.equal(12); + }); + }); + + describe("when enableCache is false", function () { + it("should not cache the API response and make a new request each time", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=3"; + conf.params.enableCache = false; + + // First call should make an API request + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + const request1 = server.requests[0]; + request1.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call should make a new API request (not use cache) + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Second call should make a new API request").to.equal(2); + + const request2 = server.requests[1]; + request2.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Both configs should have the same data structure + const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; + expect(contentData1, "First config should have Neuwo data").to.exist; + expect(contentData2, "Second config should have Neuwo data from new request").to.exist; + expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + }); + + it("should bypass existing cache when enableCache is false", function () { + const apiResponse = getNeuwoApiResponse(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=4"; + + // First call with caching enabled (default) + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + const request1 = server.requests[0]; + request1.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // Second call with caching enabled should use cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Second call should use cache").to.equal(1); + + // Third call with caching disabled should bypass cache + conf.params.enableCache = false; + neuwo.getBidRequestData(bidsConfig3, () => {}, conf, "consent data"); + expect(server.requests.length, "Third call should bypass cache and make new request").to.equal(2); + + const request2 = server.requests[1]; + request2.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); }); - it("should handle empty param list", function () { - const url = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { stripQueryParams: [] }); - expect(result, "should not strip params with empty list").to.equal(url); - }); + it("should clear pending request after error response and retry on next call", function (done) { + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=error-test"; + conf.params.enableCache = true; - it("should preserve param order for remaining params", function () { - const url = "https://example.com/page?a=1&b=2&c=3&d=4"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["b", "d"] - }); - expect(result, "should preserve order of remaining params").to.include("a=1"); - expect(result, "should preserve order of remaining params").to.include("c=3"); - expect(result, "should not include stripped param b").to.not.include("b=2"); - expect(result, "should not include stripped param d").to.not.include("d=4"); - }); - }); + // First call - will get 404 error + neuwo.getBidRequestData(bidsConfig1, () => { + // After error, data should not be injected + const contentData = bidsConfig1.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "No data should be injected after error").to.be.undefined; + + // Second call - should retry API (pending should be cleared) + neuwo.getBidRequestData(bidsConfig2, () => { + try { + expect(server.requests.length, "Second call should retry after error").to.equal(2); + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData2, "Second call should have Neuwo data after retry").to.exist; + expect(contentData2.name, "Second call should have correct provider").to.equal(neuwo.DATA_PROVIDER); + done(); + } catch (e) { + done(e); + } + }, conf, "consent data"); + + // Respond with success to second request + const request2 = server.requests[1]; + request2.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(getNeuwoApiResponse()) + ); + }, conf, "consent data"); - describe("error handling", function () { - it("should return null or undefined input unchanged", function () { - expect(neuwo.cleanUrl(null, {}), "should handle null input").to.equal(null); - expect(neuwo.cleanUrl(undefined, {}), "should handle undefined input").to.equal(undefined); - expect(neuwo.cleanUrl("", {}), "should handle empty string").to.equal(""); - }); + expect(server.requests.length, "First call should make an API request").to.equal(1); - it("should return invalid URL unchanged and log error", function () { - const invalidUrl = "not-a-valid-url"; - const result = neuwo.cleanUrl(invalidUrl, { stripAllQueryParams: true }); - expect(result, "should return invalid URL unchanged").to.equal(invalidUrl); + // Respond with error to first request + const request1 = server.requests[0]; + request1.respond( + 404, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify({ error: "Not found" }) + ); }); - it("should handle malformed URLs gracefully", function () { - const malformedUrl = "http://"; - const result = neuwo.cleanUrl(malformedUrl, { stripAllQueryParams: true }); - expect(result, "should return malformed URL unchanged").to.equal(malformedUrl); + it("should handle concurrent requests when API returns error", function (done) { + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const bidsConfig3 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=concurrent-error"; + conf.params.enableCache = true; + + let callbackCount = 0; + const callback = () => { + callbackCount++; + if (callbackCount === 3) { + try { + // None of the configs should have data after error + const contentData1 = bidsConfig1.ortb2Fragments.global?.site?.content?.data; + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data; + const contentData3 = bidsConfig3.ortb2Fragments.global?.site?.content?.data; + + expect(contentData1, "First config should not have data after error").to.be.undefined; + expect(contentData2, "Second config should not have data after error").to.be.undefined; + expect(contentData3, "Third config should not have data after error").to.be.undefined; + done(); + } catch (e) { + done(e); + } + } + }; + + // Make three concurrent calls + neuwo.getBidRequestData(bidsConfig1, callback, conf, "consent data"); + neuwo.getBidRequestData(bidsConfig2, callback, conf, "consent data"); + neuwo.getBidRequestData(bidsConfig3, callback, conf, "consent data"); + + expect(server.requests.length, "Only one API request should be made").to.equal(1); + + // Respond with error + const request = server.requests[0]; + request.respond( + 500, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify({ error: "Internal server error" }) + ); }); - }); - describe("when stripFragments is enabled", function () { - it("should strip URL fragments from URLs without query params", function () { - const url = "https://example.com/page#section"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripFragments: true }); - expect(result, "should remove hash fragment").to.equal(expected); + it("should handle JSON parsing error in success callback", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=parse-error"; + conf.params.enableCache = true; + + neuwo.getBidRequestData(bidsConfig, () => { + // Callback should still be called + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "No data should be injected after parsing error").to.be.undefined; + done(); + }, conf, "consent data"); + + expect(server.requests.length, "Should make an API request").to.equal(1); + + // Respond with invalid JSON + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + "{ invalid json content }" + ); }); - it("should strip URL fragments from URLs with query params", function () { - const url = "https://example.com/page?foo=bar#section"; - const expected = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { stripFragments: true }); - expect(result, "should remove hash fragment and preserve query params").to.equal(expected); + it("should not cache response after JSON parsing error and allow retry", function (done) { + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=parse-error-retry"; + conf.params.enableCache = true; + + neuwo.getBidRequestData(bidsConfig1, () => { + // First call with parsing error + const contentData1 = bidsConfig1.ortb2Fragments.global?.site?.content?.data; + expect(contentData1, "No data after parsing error").to.be.undefined; + + // Second call should retry (not use cached error) + neuwo.getBidRequestData(bidsConfig2, () => { + try { + expect(server.requests.length, "Should retry after parsing error").to.equal(2); + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData2, "Second call should have valid data").to.exist; + expect(contentData2.name, "Should have correct provider").to.equal(neuwo.DATA_PROVIDER); + done(); + } catch (e) { + done(e); + } + }, conf, "consent data"); + + // Second request gets valid response + const request2 = server.requests[1]; + request2.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(getNeuwoApiResponse()) + ); + }, conf, "consent data"); + + // First request gets invalid JSON + const request1 = server.requests[0]; + request1.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + "{ this is not valid JSON }" + ); }); - it("should strip fragments when combined with stripAllQueryParams", function () { - const url = "https://example.com/page?foo=bar#section"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripAllQueryParams: true, stripFragments: true }); - expect(result, "should remove both query params and fragment").to.equal(expected); + it("should handle response with empty segments", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=no-categories"; + + neuwo.getBidRequestData(bidsConfig, () => { + // Callback should still be called even with empty response + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "No data should be injected without segments").to.be.undefined; + done(); + }, conf, "consent data"); + + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify({ "6": {}, "4": {} }) // Empty segments + ); }); + }); - it("should strip fragments when combined with stripQueryParamsForDomains", function () { - const url = "https://example.com/page?foo=bar#section"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"], - stripFragments: true + describe("with URL query param stripping", function () { + describe("when stripAllQueryParams is enabled", function () { + it("should strip all query parameters from the analyzed URL", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test&utm_campaign=example&id=5"; + conf.params.stripAllQueryParams = true; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should not contain encoded query params").to.include( + encodeURIComponent("https://publisher.works/article.php") + ); + expect(request.url, "The request URL should not contain utm_source").to.not.include( + encodeURIComponent("utm_source") + ); }); - expect(result, "should remove both query params and fragment for matching domain").to.equal(expected); }); - it("should strip fragments when combined with stripQueryParams", function () { - const url = "https://example.com/page?foo=bar&keep=this#section"; - const expected = "https://example.com/page?keep=this"; - const result = neuwo.cleanUrl(url, { - stripQueryParams: ["foo"], - stripFragments: true + describe("when stripQueryParamsForDomains is enabled", function () { + it("should strip query params only for matching domains", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?foo=bar&id=5"; + conf.params.stripQueryParamsForDomains = ["publisher.works"]; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should contain the URL without query params").to.include( + encodeURIComponent("https://publisher.works/article.php") + ); + expect(request.url, "The request URL should not contain the id param").to.not.include( + encodeURIComponent("id=5") + ); }); - expect(result, "should remove specified query params and fragment").to.equal(expected); - }); - it("should handle URLs without fragments gracefully", function () { - const url = "https://example.com/page?foo=bar"; - const expected = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { stripFragments: true }); - expect(result, "should handle URLs without fragments").to.equal(expected); - }); + it("should not strip query params for non-matching domains", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://other-domain.com/page?foo=bar&id=5"; + conf.params.stripQueryParamsForDomains = ["publisher.works"]; - it("should handle empty fragments", function () { - const url = "https://example.com/page#"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { stripFragments: true }); - expect(result, "should remove empty fragment").to.equal(expected); - }); + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; - it("should handle complex fragments with special characters", function () { - const url = "https://example.com/page?foo=bar#section-1/subsection?query"; - const expected = "https://example.com/page?foo=bar"; - const result = neuwo.cleanUrl(url, { stripFragments: true }); - expect(result, "should remove complex fragments").to.equal(expected); - }); - }); + expect(request.url, "The request URL should contain the full URL with query params").to.include( + encodeURIComponent("https://other-domain.com/page?foo=bar&id=5") + ); + }); - describe("option priority", function () { - it("should apply stripAllQueryParams first when multiple options are set", function () { - const url = "https://example.com/page?foo=bar&baz=qux"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { - stripAllQueryParams: true, - stripQueryParams: ["foo"] + it("should handle subdomain matching correctly", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://sub.publisher.works/page?tracking=123"; + conf.params.stripQueryParamsForDomains = ["publisher.works"]; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should strip params for subdomain").to.include( + encodeURIComponent("https://sub.publisher.works/page") + ); + expect(request.url, "The request URL should not contain tracking param").to.not.include( + encodeURIComponent("tracking=123") + ); }); - expect(result, "stripAllQueryParams should take precedence").to.equal(expected); }); - it("should apply stripQueryParamsForDomains before stripQueryParams", function () { - const url = "https://example.com/page?foo=bar&baz=qux"; - const expected = "https://example.com/page"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"], - stripQueryParams: ["foo"] + describe("when stripQueryParams is enabled", function () { + it("should strip only specified query parameters", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test&utm_campaign=example&id=5"; + conf.params.stripQueryParams = ["utm_source", "utm_campaign"]; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should contain the id param").to.include( + encodeURIComponent("id=5") + ); + expect(request.url, "The request URL should not contain utm_source").to.not.include( + encodeURIComponent("utm_source") + ); + expect(request.url, "The request URL should not contain utm_campaign").to.not.include( + encodeURIComponent("utm_campaign") + ); }); - expect(result, "domain-specific stripping should take precedence").to.equal(expected); - }); - it("should not strip for non-matching domain even with stripQueryParams set", function () { - const url = "https://other.com/page?foo=bar&baz=qux"; - const expected = "https://other.com/page?baz=qux"; - const result = neuwo.cleanUrl(url, { - stripQueryParamsForDomains: ["example.com"], - stripQueryParams: ["foo"] + it("should handle stripping params that result in no query string", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test"; + conf.params.stripQueryParams = ["utm_source"]; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should not contain a query string").to.include( + encodeURIComponent("https://publisher.works/article.php") + ); + expect(request.url, "The request URL should not contain utm_source").to.not.include( + encodeURIComponent("utm_source") + ); }); - expect(result, "should fall through to stripQueryParams for non-matching domain").to.equal(expected); - }); - }); - }); - // Integration Tests - describe("injectIabCategories edge cases and merging", function () { - it("should not inject data if 'marketing_categories' is missing from the successful API response", function () { - const apiResponse = { brand_safety: { BS_score: "1.0" } }; // Missing marketing_categories - const bidsConfig = bidsConfiglike(); - const bidsConfigCopy = bidsConfiglike(); - const conf = config(); + it("should leave URL unchanged if specified params do not exist", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + const originalUrl = "https://publisher.works/article.php?id=5"; + conf.params.websiteToAnalyseUrl = originalUrl; + conf.params.stripQueryParams = ["utm_source", "nonexistent"]; - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; - // After a successful response with missing data, the global ortb2 fragments should remain empty - // as the data injection logic checks for marketingCategories. - expect( - bidsConfig.ortb2Fragments.global, - "The global ORTB fragments should remain empty" - ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); - }); + expect(request.url, "The request URL should contain the original URL").to.include( + encodeURIComponent(originalUrl) + ); + }); + }); - it("should append content and user data to existing ORTB fragments", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig = bidsConfiglike(); - // Simulate existing first-party data from another source/module - const existingContentData = { name: "other_content_provider", segment: [{ id: "1" }] }; - const existingUserData = { name: "other_user_provider", segment: [{ id: "2" }] }; + describe("when no stripping options are provided", function () { + it("should send the URL with all query parameters intact", function () { + const bidsConfig = bidsConfiglike(); + const conf = config(); + const originalUrl = "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + conf.params.websiteToAnalyseUrl = originalUrl; - bidsConfig.ortb2Fragments.global = { - site: { - content: { - data: [existingContentData], - }, - }, - user: { - data: [existingUserData], - }, - }; - const conf = config(); + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; - request.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + expect(request.url, "The request URL should contain the full original URL").to.include( + encodeURIComponent(originalUrl) + ); + }); + }); + }); + }); - const siteData = bidsConfig.ortb2Fragments.global.site.content.data; - const userData = bidsConfig.ortb2Fragments.global.user.data; + // V1 API Format Tests + // These tests use the legacy V1 API response format with marketing_categories structure. + // V1 API uses GET requests and returns: { marketing_categories: { iab_tier_1: [], iab_tier_2: [], etc. } } + // Field names in V1: ID, label, relevance (capital letters) + describe("V1 API", function () { + describe("getBidRequestData", function () { + describe("when using IAB Content Taxonomy 3.0", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + // control xhr api request target for testing + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + expect(request.url, "The request URL should include the product identifier").to.include( + "_neuwo_prod=PrebidModule" + ); + expect(request.url, "V1 API should NOT include iabVersions parameter").to.not.include( + "iabVersions" + ); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + const contentData = bidsConfig.ortb2Fragments.global.site.content.data[0]; + expect(contentData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + contentData.ext.segtax, + "The segtax value should correspond to IAB Content Taxonomy 3.0" + ).to.equal(7); + expect( + contentData.segment[0].id, + "The first segment ID should match the API response (transformed from V1)" + ).to.equal(apiResponse.marketing_categories.iab_tier_1[0].ID); + expect( + contentData.segment[1].id, + "The second segment ID should match the API response (transformed from V1)" + ).to.equal(apiResponse.marketing_categories.iab_tier_2[0].ID); + }); + }); - // Check that the existing data is still there (index 0) - expect(siteData[0], "Existing site.content.data should be preserved").to.deep.equal( - existingContentData - ); - expect(userData[0], "Existing user.data should be preserved").to.deep.equal(existingUserData); + describe("when using IAB Audience Taxonomy 1.1", function () { + it("should correctly structure the bids object after a successful API response", function () { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + // control xhr api request target for testing + conf.params.websiteToAnalyseUrl = + "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + + expect(request.url, "The request URL should be a string").to.be.a("string"); + expect(request.url, "The request URL should include the public API token").to.include( + conf.params.neuwoApiToken + ); + expect(request.url, "The request URL should include the encoded website URL").to.include( + encodeURIComponent(conf.params.websiteToAnalyseUrl) + ); + + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + const userData = bidsConfig.ortb2Fragments.global.user.data[0]; + expect(userData.name, "The data provider name should be correctly set").to.equal( + neuwo.DATA_PROVIDER + ); + expect( + userData.ext.segtax, + "The segtax value should correspond to IAB Audience Taxonomy 1.1" + ).to.equal(4); + expect( + userData.segment[0].id, + "The first segment ID should match the API response (transformed from V1)" + ).to.equal(apiResponse.marketing_categories.iab_audience_tier_3[0].ID); + expect( + userData.segment[1].id, + "The second segment ID should match the API response (transformed from V1)" + ).to.equal(apiResponse.marketing_categories.iab_audience_tier_4[0].ID); + }); + }); - // Check that the new Neuwo data is appended (index 1) - expect(siteData.length, "site.content.data array should have 2 entries").to.equal(2); - expect(userData.length, "user.data array should have 2 entries").to.equal(2); - expect(siteData[1].name, "The appended content data should be from Neuwo").to.equal( - neuwo.DATA_PROVIDER - ); - expect(userData[1].name, "The appended user data should be from Neuwo").to.equal( - neuwo.DATA_PROVIDER - ); + describe("edge cases", function () { + it("should not inject data if 'marketing_categories' is missing from the successful API response", function () { + const apiResponse = { brand_safety: { BS_score: "1.0" } }; // Missing marketing_categories + const bidsConfig = bidsConfiglike(); + const bidsConfigCopy = bidsConfiglike(); + const conf = configV1(); + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + + // After a successful response with missing data, the global ortb2 fragments should remain empty + // as the data injection logic checks for marketing_categories in V1 format + expect( + bidsConfig.ortb2Fragments.global, + "The global ORTB fragments should remain empty" + ).to.deep.equal(bidsConfigCopy.ortb2Fragments.global); + }); + + it("should handle response with missing marketing_categories", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=no-categories"; + + neuwo.getBidRequestData(bidsConfig, () => { + // Callback should still be called even without marketing_categories + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "No data should be injected without marketing_categories").to.be.undefined; + done(); + }, conf, "consent data"); + + const request = server.requests[0]; + request.respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify({ brand_safety: { BS_score: "1.0" } }) // Missing marketing_categories + ); + }); + }); }); - }); - describe("getBidRequestData with caching", function () { - describe("when enableCache is true (default)", function () { - it("should cache the API response and reuse it on subsequent calls", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig1 = bidsConfiglike(); - const bidsConfig2 = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=1"; + describe("with iabTaxonomyFilters (client-side filtering)", function () { + it("should work without filtering when no iabTaxonomyFilters provided", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + + neuwo.getBidRequestData( + bidsConfig, + () => { + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + + expect(contentData, "should have content data").to.exist; + expect(contentData.segment, "should have unfiltered content segments").to.have.lengthOf(2); + expect(userData, "should have user data").to.exist; + expect(userData.segment, "should have unfiltered audience segments").to.have.lengthOf(3); + done(); + }, + conf, + "consent data" + ); - // First call should make an API request - neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); - expect(server.requests.length, "First call should make an API request").to.equal(1); + const request = server.requests[0]; + request.respond(200, {}, JSON.stringify(getNeuwoApiResponseV1())); + }); - const request1 = server.requests[0]; - request1.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) + it("should apply client-side filtering when iabTaxonomyFilters are provided", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + conf.params.iabTaxonomyFilters = { + ContentTier1: { limit: 1, threshold: 0.4 }, + AudienceTier3: { limit: 1, threshold: 0.9 } + }; + + neuwo.getBidRequestData( + bidsConfig, + () => { + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data?.[0]; + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + + expect(contentData, "should have content data").to.exist; + expect(contentData.segment, "should have filtered content segments").to.have.lengthOf(2); + + // Check that tier 1 was limited to 1 + const tier1Items = contentData.segment.filter(s => s.id === "274"); + expect(tier1Items, "should have only 1 tier 1 item").to.have.lengthOf(1); + + expect(userData, "should have user data").to.exist; + // Audience tier 3 should be filtered to 1, but tiers 4 and 5 should remain + expect(userData.segment, "should have filtered audience segments").to.have.lengthOf(3); + + done(); + }, + conf, + "consent data" ); - // Second call should use cached response (no new API request) - neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); - expect(server.requests.length, "Second call should not make a new API request").to.equal(1); + const request = server.requests[0]; + request.respond(200, {}, JSON.stringify(getNeuwoApiResponseV1())); + }); + + it("should apply strict client-side filtering that removes all low-relevance items", function (done) { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + conf.params.iabTaxonomyFilters = { + ContentTier1: { threshold: 0.9 }, // Only keep items with 90%+ relevance + ContentTier2: { threshold: 0.9 }, + AudienceTier4: { threshold: 0.99 }, + AudienceTier5: { threshold: 0.99 } + }; + + neuwo.getBidRequestData( + bidsConfig, + () => { + // Tier 1 has 0.47, Tier 2 has 0.41 - both below 0.9 threshold + // All content segments are filtered out, so content data should not be injected + const contentData = bidsConfig.ortb2Fragments.global?.site?.content?.data; + expect(contentData, "should not inject content data when all segments filtered out").to.be.undefined; + + const userData = bidsConfig.ortb2Fragments.global?.user?.data?.[0]; + expect(userData, "should have user data").to.exist; + // Tier 3 has 0.9923 (passes), Tier 4 has 0.9673 (fails), Tier 5 has 0.9066 (fails) + expect(userData.segment, "should have only 1 audience segment").to.have.lengthOf(1); + + done(); + }, + conf, + "consent data" + ); - // Both configs should have the same data - const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; - const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; - expect(contentData1, "First config should have Neuwo data").to.exist; - expect(contentData2, "Second config should have Neuwo data from cache").to.exist; - expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); - expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + const request = server.requests[0]; + request.respond(200, {}, JSON.stringify(getNeuwoApiResponseV1())); }); - it("should cache when enableCache is explicitly set to true", function () { - const apiResponse = getNeuwoApiResponse(); + it("should handle client-side filtering with cached response", function (done) { const bidsConfig1 = bidsConfiglike(); const bidsConfig2 = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=2"; - conf.params.enableCache = true; + const conf = configV1(); + conf.params.iabTaxonomyFilters = { + ContentTier1: { limit: 1 } + }; + + // First request + neuwo.getBidRequestData( + bidsConfig1, + () => { + // Second request (should use cache) + neuwo.getBidRequestData( + bidsConfig2, + () => { + const contentData = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData, "should have content data from cache").to.exist; + expect(contentData.segment, "should apply filtering to cached response").to.have.lengthOf(2); + done(); + }, + conf, + "consent data" + ); + }, + conf, + "consent data" + ); - // First call - neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); - expect(server.requests.length, "First call should make an API request").to.equal(1); + const request = server.requests[0]; + expect(server.requests, "should only make one API request").to.have.lengthOf(1); + request.respond(200, {}, JSON.stringify(getNeuwoApiResponseV1())); + }); + }); - const request1 = server.requests[0]; - request1.respond( + describe("OpenRTB 2.5 category fields (V1 API compatibility)", function () { + it("should not include iabVersions parameter with legacy API", function () { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + conf.params.enableOrtb25Fields = true; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + + const request = server.requests[0]; + expect(request.url, "should not include iabVersions parameter").to.not.include("iabVersions"); + }); + + it("should not inject category fields with legacy API", function () { + const bidsConfig = bidsConfiglike(); + const conf = configV1(); + conf.params.enableOrtb25Fields = true; + + neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); + const request = server.requests[0]; + request.respond( 200, { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) + JSON.stringify(getNeuwoApiResponseV1()) ); - // Second call should use cache - neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); - expect(server.requests.length, "Second call should use cached response").to.equal(1); + const siteCat = bidsConfig.ortb2Fragments.global?.site?.cat; + expect(siteCat, "should not have site.cat with legacy API").to.be.undefined; }); }); - describe("when enableCache is false", function () { - it("should not cache the API response and make a new request each time", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig1 = bidsConfiglike(); - const bidsConfig2 = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=3"; - conf.params.enableCache = false; + describe("filterIabTaxonomyTier", function () { + it("should return original array when no filter is provided", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" }, + { ID: "3", label: "Category 3", relevance: "0.3" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, {}); + expect(result, "should return all items when no filter is provided").to.have.lengthOf(3); + }); - // First call should make an API request - neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); - expect(server.requests.length, "First call should make an API request").to.equal(1); + it("should return original array when filter is empty", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies); + expect(result, "should return all items when no filter parameter").to.have.lengthOf(2); + }); - const request1 = server.requests[0]; - request1.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + it("should filter by threshold only", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" }, + { ID: "3", label: "Category 3", relevance: "0.3" }, + { ID: "4", label: "Category 4", relevance: "0.1" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { threshold: 0.4 }); + expect(result, "should filter out items below threshold").to.have.lengthOf(2); + expect(result[0].ID, "should keep highest relevance item").to.equal("1"); + expect(result[1].ID, "should keep second highest relevance item").to.equal("2"); + }); - // Second call should make a new API request (not use cache) - neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); - expect(server.requests.length, "Second call should make a new API request").to.equal(2); + it("should limit by count only", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" }, + { ID: "3", label: "Category 3", relevance: "0.3" }, + { ID: "4", label: "Category 4", relevance: "0.1" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { limit: 2 }); + expect(result, "should limit to specified count").to.have.lengthOf(2); + expect(result[0].ID, "should keep highest relevance item").to.equal("1"); + expect(result[1].ID, "should keep second highest relevance item").to.equal("2"); + }); - const request2 = server.requests[1]; - request2.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + it("should return empty array when limit is 0", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { limit: 0 }); + expect(result, "limit 0 should suppress the tier entirely").to.be.an("array").that.is.empty; + }); - // Both configs should have the same data structure - const contentData1 = bidsConfig1.ortb2Fragments.global.site.content.data[0]; - const contentData2 = bidsConfig2.ortb2Fragments.global.site.content.data[0]; - expect(contentData1, "First config should have Neuwo data").to.exist; - expect(contentData2, "Second config should have Neuwo data from new request").to.exist; - expect(contentData1.name, "First config should have correct provider").to.equal(neuwo.DATA_PROVIDER); - expect(contentData2.name, "Second config should have correct provider").to.equal(neuwo.DATA_PROVIDER); + it("should apply both threshold and limit", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.9" }, + { ID: "2", label: "Category 2", relevance: "0.7" }, + { ID: "3", label: "Category 3", relevance: "0.6" }, + { ID: "4", label: "Category 4", relevance: "0.5" }, + { ID: "5", label: "Category 5", relevance: "0.2" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { threshold: 0.5, limit: 2 }); + expect(result, "should apply both threshold and limit").to.have.lengthOf(2); + expect(result[0].ID, "should keep highest relevance item").to.equal("1"); + expect(result[1].ID, "should keep second highest relevance item").to.equal("2"); }); - it("should bypass existing cache when enableCache is false", function () { - const apiResponse = getNeuwoApiResponse(); - const bidsConfig1 = bidsConfiglike(); - const bidsConfig2 = bidsConfiglike(); - const bidsConfig3 = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?id=4"; + it("should preserve original order when filter is empty", function () { + const taxonomies = [ + { ID: "3", label: "Category 3", relevance: "0.3" }, + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, {}); + expect(result[0].ID, "first item should keep original position").to.equal("3"); + expect(result[1].ID, "second item should keep original position").to.equal("1"); + expect(result[2].ID, "third item should keep original position").to.equal("2"); + }); - // First call with caching enabled (default) - neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); - expect(server.requests.length, "First call should make an API request").to.equal(1); + it("should sort by relevance descending only when limit is set", function () { + const taxonomies = [ + { ID: "3", label: "Category 3", relevance: "0.3" }, + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { limit: 2 }); + expect(result).to.have.lengthOf(2); + expect(result[0].ID, "first item should have highest relevance").to.equal("1"); + expect(result[1].ID, "second item should have second highest relevance").to.equal("2"); + }); - const request1 = server.requests[0]; - request1.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + it("should not sort when only threshold is set", function () { + const taxonomies = [ + { ID: "3", label: "Category 3", relevance: "0.6" }, + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.2" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { threshold: 0.5 }); + expect(result).to.have.lengthOf(2); + expect(result[0].ID, "should preserve original order after threshold filter").to.equal("3"); + expect(result[1].ID, "should preserve original order after threshold filter").to.equal("1"); + }); - // Second call with caching enabled should use cache - neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); - expect(server.requests.length, "Second call should use cache").to.equal(1); + it("should handle empty array", function () { + const result = neuwo.filterIabTaxonomyTier([], { threshold: 0.5, limit: 2 }); + expect(result, "should return empty array for empty input").to.be.an("array").that.is.empty; + }); - // Third call with caching disabled should bypass cache - conf.params.enableCache = false; - neuwo.getBidRequestData(bidsConfig3, () => {}, conf, "consent data"); - expect(server.requests.length, "Third call should bypass cache and make new request").to.equal(2); + it("should handle null input", function () { + const result = neuwo.filterIabTaxonomyTier(null, { threshold: 0.5 }); + expect(result, "should return empty array for null input").to.be.an("array").that.is.empty; + }); - const request2 = server.requests[1]; - request2.respond( - 200, - { "Content-Type": "application/json; encoding=UTF-8" }, - JSON.stringify(apiResponse) - ); + it("should handle undefined input", function () { + const result = neuwo.filterIabTaxonomyTier(undefined, { threshold: 0.5 }); + expect(result, "should return empty array for undefined input").to.be.an("array").that.is.empty; + }); + + it("should handle items with missing relevance", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2" }, + { ID: "3", label: "Category 3", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { threshold: 0.3 }); + expect(result, "should handle missing relevance").to.have.lengthOf(2); + }); + + it("should not mutate original array", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2", relevance: "0.5" }, + { ID: "3", label: "Category 3", relevance: "0.3" } + ]; + const original = [...taxonomies]; + neuwo.filterIabTaxonomyTier(taxonomies, { limit: 1 }); + expect(taxonomies, "should not mutate original array").to.deep.equal(original); + }); + + it("should sort items with undefined/null relevance to the end", function () { + const taxonomies = [ + { ID: "1", label: "Category 1", relevance: "0.8" }, + { ID: "2", label: "Category 2" }, // missing relevance + { ID: "3", label: "Category 3", relevance: null }, + { ID: "4", label: "Category 4", relevance: undefined }, + { ID: "5", label: "Category 5", relevance: "0.5" } + ]; + const result = neuwo.filterIabTaxonomyTier(taxonomies, { limit: 5 }); + expect(result, "should return all items").to.have.lengthOf(5); + expect(result[0].ID, "should have highest relevance first").to.equal("1"); + expect(result[1].ID, "should have second highest relevance").to.equal("5"); + // Items with missing/null/undefined relevance should be sorted to the end + const lastThreeIds = [result[2].ID, result[3].ID, result[4].ID].sort(); + expect(lastThreeIds, "items with no relevance should be at the end").to.deep.equal(["2", "3", "4"]); }); }); - }); - describe("getBidRequestData with URL query param stripping", function () { - describe("when stripAllQueryParams is enabled", function () { - it("should strip all query parameters from the analyzed URL", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test&utm_campaign=example&id=5"; - conf.params.stripAllQueryParams = true; + describe("filterIabTaxonomies", function () { + function getTestMarketingCategories() { + return { + iab_tier_1: [ + { ID: "1", label: "Cat 1", relevance: "0.9" }, + { ID: "2", label: "Cat 2", relevance: "0.7" }, + { ID: "3", label: "Cat 3", relevance: "0.5" } + ], + iab_tier_2: [ + { ID: "4", label: "Cat 4", relevance: "0.8" }, + { ID: "5", label: "Cat 5", relevance: "0.6" } + ], + iab_audience_tier_3: [ + { ID: "6", label: "Aud 1", relevance: "0.95" }, + { ID: "7", label: "Aud 2", relevance: "0.85" }, + { ID: "8", label: "Aud 3", relevance: "0.75" } + ] + }; + } + + it("should return original data when no filters provided", function () { + const marketingCategories = getTestMarketingCategories(); + const result = neuwo.filterIabTaxonomies(marketingCategories, {}); + expect(result.iab_tier_1, "should return all tier 1 items").to.have.lengthOf(3); + expect(result.iab_tier_2, "should return all tier 2 items").to.have.lengthOf(2); + expect(result.iab_audience_tier_3, "should return all audience tier 3 items").to.have.lengthOf(3); + }); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + it("should return original data when filters parameter is undefined", function () { + const marketingCategories = getTestMarketingCategories(); + const result = neuwo.filterIabTaxonomies(marketingCategories); + expect(result.iab_tier_1, "should return all tier 1 items").to.have.lengthOf(3); + }); - expect(request.url, "The request URL should not contain encoded query params").to.include( - encodeURIComponent("https://publisher.works/article.php") - ); - expect(request.url, "The request URL should not contain utm_source").to.not.include( - encodeURIComponent("utm_source") - ); + it("should filter ContentTier1 correctly", function () { + const marketingCategories = getTestMarketingCategories(); + const filters = { + ContentTier1: { limit: 1, threshold: 0.8 } + }; + const result = neuwo.filterIabTaxonomies(marketingCategories, filters); + expect(result.iab_tier_1, "should filter tier 1").to.have.lengthOf(1); + expect(result.iab_tier_1[0].ID, "should keep highest relevance item").to.equal("1"); + expect(result.iab_tier_2, "should not filter tier 2").to.have.lengthOf(2); + }); + + it("should filter multiple tiers independently", function () { + const marketingCategories = getTestMarketingCategories(); + const filters = { + ContentTier1: { limit: 2, threshold: 0.6 }, + ContentTier2: { limit: 1, threshold: 0.7 }, + AudienceTier3: { limit: 2, threshold: 0.8 } + }; + const result = neuwo.filterIabTaxonomies(marketingCategories, filters); + expect(result.iab_tier_1, "should filter tier 1 to 2 items").to.have.lengthOf(2); + expect(result.iab_tier_2, "should filter tier 2 to 1 item").to.have.lengthOf(1); + expect(result.iab_tier_2[0].ID, "tier 2 should keep highest item").to.equal("4"); + expect(result.iab_audience_tier_3, "should filter audience tier 3 to 2 items").to.have.lengthOf(2); + }); + + it("should handle tier with no matching config", function () { + const marketingCategories = getTestMarketingCategories(); + const filters = { + ContentTier1: { limit: 1 } + }; + const result = neuwo.filterIabTaxonomies(marketingCategories, filters); + expect(result.iab_tier_1, "should filter configured tier").to.have.lengthOf(1); + expect(result.iab_tier_2, "should keep all items in non-configured tier").to.have.lengthOf(2); + }); + + it("should preserve non-array tier data", function () { + const marketingCategories = { + iab_tier_1: [{ ID: "1", label: "Cat 1", relevance: "0.9" }], + some_other_field: "string value", + another_field: 123 + }; + const filters = { + ContentTier1: { limit: 1 } + }; + const result = neuwo.filterIabTaxonomies(marketingCategories, filters); + expect(result.some_other_field, "should preserve string field").to.equal("string value"); + expect(result.another_field, "should preserve number field").to.equal(123); + }); + + it("should handle null marketingCategories", function () { + const result = neuwo.filterIabTaxonomies(null, { ContentTier1: { limit: 1 } }); + expect(result, "should return null for null input").to.be.null; + }); + + it("should handle undefined marketingCategories", function () { + const result = neuwo.filterIabTaxonomies(undefined, { ContentTier1: { limit: 1 } }); + expect(result, "should return undefined for undefined input").to.be.undefined; + }); + + it("should handle all tier configurations", function () { + const marketingCategories = { + iab_tier_1: [ + { ID: "1", label: "C1", relevance: "0.9" }, + { ID: "2", label: "C2", relevance: "0.5" } + ], + iab_tier_2: [ + { ID: "3", label: "C3", relevance: "0.8" }, + { ID: "4", label: "C4", relevance: "0.4" } + ], + iab_tier_3: [ + { ID: "5", label: "C5", relevance: "0.7" }, + { ID: "6", label: "C6", relevance: "0.3" } + ], + iab_audience_tier_3: [ + { ID: "7", label: "A1", relevance: "0.95" }, + { ID: "8", label: "A2", relevance: "0.45" } + ], + iab_audience_tier_4: [ + { ID: "9", label: "A3", relevance: "0.85" }, + { ID: "10", label: "A4", relevance: "0.35" } + ], + iab_audience_tier_5: [ + { ID: "11", label: "A5", relevance: "0.75" }, + { ID: "12", label: "A6", relevance: "0.25" } + ] + }; + const filters = { + ContentTier1: { limit: 1, threshold: 0.8 }, + ContentTier2: { limit: 1, threshold: 0.7 }, + ContentTier3: { limit: 1, threshold: 0.6 }, + AudienceTier3: { limit: 1, threshold: 0.9 }, + AudienceTier4: { limit: 1, threshold: 0.8 }, + AudienceTier5: { limit: 1, threshold: 0.7 } + }; + const result = neuwo.filterIabTaxonomies(marketingCategories, filters); + expect(result.iab_tier_1, "ContentTier1 filtered").to.have.lengthOf(1); + expect(result.iab_tier_2, "ContentTier2 filtered").to.have.lengthOf(1); + expect(result.iab_tier_3, "ContentTier3 filtered").to.have.lengthOf(1); + expect(result.iab_audience_tier_3, "AudienceTier3 filtered").to.have.lengthOf(1); + expect(result.iab_audience_tier_4, "AudienceTier4 filtered").to.have.lengthOf(1); + expect(result.iab_audience_tier_5, "AudienceTier5 filtered").to.have.lengthOf(1); }); }); - describe("when stripQueryParamsForDomains is enabled", function () { - it("should strip query params only for matching domains", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?foo=bar&id=5"; - conf.params.stripQueryParamsForDomains = ["publisher.works"]; + describe("transformSegmentsV1ToV2", function () { + it("should transform V1 segment format to V2 format", function () { + const v1Segments = [ + { ID: "274", label: "Home & Garden", relevance: "0.47" }, + { ID: "216", label: "Cooking", relevance: "0.41" } + ]; + const result = neuwo.transformSegmentsV1ToV2(v1Segments); + + expect(result, "should return array with same length").to.have.lengthOf(2); + expect(result[0], "first segment should have id property").to.have.property("id", "274"); + expect(result[0], "first segment should have name property").to.have.property("name", "Home & Garden"); + expect(result[0], "first segment should have relevance property").to.have.property("relevance", "0.47"); + expect(result[1], "second segment should have id property").to.have.property("id", "216"); + expect(result[1], "second segment should have name property").to.have.property("name", "Cooking"); + expect(result[1], "second segment should have relevance property").to.have.property("relevance", "0.41"); + }); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + it("should handle empty array", function () { + const result = neuwo.transformSegmentsV1ToV2([]); + expect(result, "should return empty array").to.be.an("array").that.is.empty; + }); - expect(request.url, "The request URL should contain the URL without query params").to.include( - encodeURIComponent("https://publisher.works/article.php") - ); - expect(request.url, "The request URL should not contain the id param").to.not.include( - encodeURIComponent("id=5") - ); + it("should handle null input", function () { + const result = neuwo.transformSegmentsV1ToV2(null); + expect(result, "should return empty array for null").to.be.an("array").that.is.empty; }); - it("should not strip query params for non-matching domains", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://other-domain.com/page?foo=bar&id=5"; - conf.params.stripQueryParamsForDomains = ["publisher.works"]; + it("should handle undefined input", function () { + const result = neuwo.transformSegmentsV1ToV2(undefined); + expect(result, "should return empty array for undefined").to.be.an("array").that.is.empty; + }); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + it("should handle non-array input", function () { + const result = neuwo.transformSegmentsV1ToV2("not an array"); + expect(result, "should return empty array for non-array").to.be.an("array").that.is.empty; + }); - expect(request.url, "The request URL should contain the full URL with query params").to.include( - encodeURIComponent("https://other-domain.com/page?foo=bar&id=5") - ); + it("should handle segments with missing properties", function () { + const v1Segments = [ + { ID: "274", label: "Home & Garden" }, // missing relevance + { ID: "216", relevance: "0.41" }, // missing label + { label: "Test", relevance: "0.5" } // missing ID + ]; + const result = neuwo.transformSegmentsV1ToV2(v1Segments); + + expect(result, "should return array with same length").to.have.lengthOf(3); + expect(result[0].id, "should handle missing relevance").to.equal("274"); + expect(result[0].relevance, "should set undefined for missing relevance").to.be.undefined; + expect(result[1].name, "should set undefined for missing label").to.be.undefined; + expect(result[2].id, "should set undefined for missing ID").to.be.undefined; }); - it("should handle subdomain matching correctly", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://sub.publisher.works/page?tracking=123"; - conf.params.stripQueryParamsForDomains = ["publisher.works"]; + it("should preserve all properties from V1 format", function () { + const v1Segments = [ + { ID: "49", label: "Female", relevance: "0.9923" } + ]; + const result = neuwo.transformSegmentsV1ToV2(v1Segments); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + expect(result[0], "should only have id, name, and relevance properties").to.have.all.keys("id", "name", "relevance"); + }); + }); - expect(request.url, "The request URL should strip params for subdomain").to.include( - encodeURIComponent("https://sub.publisher.works/page") - ); - expect(request.url, "The request URL should not contain tracking param").to.not.include( - encodeURIComponent("tracking=123") - ); + describe("transformV1ResponseToV2", function () { + it("should transform complete V1 response to V2 format", function () { + const v1Response = { + marketing_categories: { + iab_tier_1: [{ ID: "274", label: "Home & Garden", relevance: "0.47" }], + iab_tier_2: [{ ID: "216", label: "Cooking", relevance: "0.41" }], + iab_tier_3: [{ ID: "388", label: "Recipes", relevance: "0.35" }], + iab_audience_tier_3: [{ ID: "49", label: "Female", relevance: "0.9923" }], + iab_audience_tier_4: [{ ID: "431", label: "Age 25-34", relevance: "0.9673" }], + iab_audience_tier_5: [{ ID: "98", label: "Interest: Cooking", relevance: "0.9066" }] + } + }; + const contentSegtax = 7; // IAB Content Taxonomy 3.0 + const result = neuwo.transformV1ResponseToV2(v1Response, contentSegtax); + + expect(result, "should have content segtax key").to.have.property("7"); + expect(result, "should have audience segtax key").to.have.property("4"); + expect(result["7"], "content segtax should have all tiers").to.have.all.keys("1", "2", "3"); + expect(result["4"], "audience segtax should have all tiers").to.have.all.keys("3", "4", "5"); + expect(result["7"]["1"][0], "content tier 1 should be transformed").to.deep.equal({ + id: "274", + name: "Home & Garden", + relevance: "0.47" + }); + expect(result["4"]["3"][0], "audience tier 3 should be transformed").to.deep.equal({ + id: "49", + name: "Female", + relevance: "0.9923" + }); + }); + + it("should handle different content segtax values", function () { + const v1Response = { + marketing_categories: { + iab_tier_1: [{ ID: "274", label: "Home & Garden", relevance: "0.47" }] + } + }; + + // Test with segtax 6 (IAB 2.2) + const result6 = neuwo.transformV1ResponseToV2(v1Response, 6); + expect(result6, "should use segtax 6 for content").to.have.property("6"); + expect(result6["6"], "should have tier 1").to.have.property("1"); + + // Test with segtax 1 (IAB 1.0) + const result1 = neuwo.transformV1ResponseToV2(v1Response, 1); + expect(result1, "should use segtax 1 for content").to.have.property("1"); + expect(result1["1"], "should have tier 1").to.have.property("1"); + }); + + it("should handle missing marketing_categories", function () { + const v1Response = {}; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(result, "should have content segtax key").to.have.property("6"); + expect(result, "should have audience segtax key").to.have.property("4"); + expect(result["6"], "content segtax should be empty object").to.deep.equal({}); + expect(result["4"], "audience segtax should be empty object").to.deep.equal({}); + }); + + it("should handle null v1Response", function () { + const result = neuwo.transformV1ResponseToV2(null, 6); + + expect(result, "should have content segtax key").to.have.property("6"); + expect(result, "should have audience segtax key").to.have.property("4"); + expect(result["6"], "content segtax should be empty object").to.deep.equal({}); + expect(result["4"], "audience segtax should be empty object").to.deep.equal({}); + }); + + it("should handle undefined v1Response", function () { + const result = neuwo.transformV1ResponseToV2(undefined, 6); + + expect(result, "should have content segtax key").to.have.property("6"); + expect(result, "should have audience segtax key").to.have.property("4"); + expect(result["6"], "content segtax should be empty object").to.deep.equal({}); + expect(result["4"], "audience segtax should be empty object").to.deep.equal({}); + }); + + it("should handle partial V1 response with only content tiers", function () { + const v1Response = { + marketing_categories: { + iab_tier_1: [{ ID: "274", label: "Home & Garden", relevance: "0.47" }], + iab_tier_2: [{ ID: "216", label: "Cooking", relevance: "0.41" }] + // No tier 3, no audience tiers + } + }; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(result["6"], "should have only tier 1 and 2").to.have.all.keys("1", "2"); + expect(result["6"], "should not have tier 3").to.not.have.property("3"); + expect(result["4"], "audience segtax should be empty").to.deep.equal({}); + }); + + it("should handle partial V1 response with only audience tiers", function () { + const v1Response = { + marketing_categories: { + iab_audience_tier_3: [{ ID: "49", label: "Female", relevance: "0.9923" }], + iab_audience_tier_4: [{ ID: "431", label: "Age 25-34", relevance: "0.9673" }] + // No content tiers + } + }; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(result["6"], "content segtax should be empty").to.deep.equal({}); + expect(result["4"], "should have tier 3 and 4").to.have.all.keys("3", "4"); + expect(result["4"], "should not have tier 5").to.not.have.property("5"); + }); + + it("should handle empty arrays in V1 response", function () { + const v1Response = { + marketing_categories: { + iab_tier_1: [], + iab_tier_2: [], + iab_audience_tier_3: [] + } + }; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(result["6"]["1"], "content tier 1 should be empty array").to.be.an("array").that.is.empty; + expect(result["6"]["2"], "content tier 2 should be empty array").to.be.an("array").that.is.empty; + expect(result["4"]["3"], "audience tier 3 should be empty array").to.be.an("array").that.is.empty; + }); + + it("should convert segtax to string keys", function () { + const v1Response = { + marketing_categories: { + iab_tier_1: [{ ID: "274", label: "Home & Garden", relevance: "0.47" }] + } + }; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(Object.keys(result), "segtax keys should be strings").to.include.members(["6", "4"]); + expect(typeof Object.keys(result)[0], "key type should be string").to.equal("string"); + }); + + it("should preserve brand_safety and other non-marketing_categories fields", function () { + const v1Response = { + brand_safety: { BS_score: "1.0" }, + marketing_categories: { + iab_tier_1: [{ ID: "274", label: "Home & Garden", relevance: "0.47" }] + }, + custom_field: "value" + }; + const result = neuwo.transformV1ResponseToV2(v1Response, 6); + + expect(result, "should not have brand_safety").to.not.have.property("brand_safety"); + expect(result, "should not have custom_field").to.not.have.property("custom_field"); + expect(result, "should only have segtax keys").to.have.all.keys("6", "4"); }); }); - describe("when stripQueryParams is enabled", function () { - it("should strip only specified query parameters", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test&utm_campaign=example&id=5"; - conf.params.stripQueryParams = ["utm_source", "utm_campaign"]; + describe("getBidRequestData with caching (legacy cache key isolation)", function () { + beforeEach(function () { + neuwo.clearCache(); + }); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + it("should not share cache between different iabContentTaxonomyVersion values", function () { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf1 = configV1(); + conf1.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf1.params.enableCache = true; + conf1.params.iabContentTaxonomyVersion = "3.0"; + + const conf2 = configV1(); + conf2.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf2.params.enableCache = true; + conf2.params.iabContentTaxonomyVersion = "2.2"; + + // First call with taxonomy 3.0 + neuwo.getBidRequestData(bidsConfig1, () => {}, conf1, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); - expect(request.url, "The request URL should contain the id param").to.include( - encodeURIComponent("id=5") - ); - expect(request.url, "The request URL should not contain utm_source").to.not.include( - encodeURIComponent("utm_source") - ); - expect(request.url, "The request URL should not contain utm_campaign").to.not.include( - encodeURIComponent("utm_campaign") + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) ); - }); - it("should handle stripping params that result in no query string", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - conf.params.websiteToAnalyseUrl = "https://publisher.works/article.php?utm_source=test"; - conf.params.stripQueryParams = ["utm_source"]; + // Verify first call has content under segtax 7 (taxonomy 3.0) + const contentData1 = bidsConfig1.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData1, "First call should have content data").to.exist; + expect(contentData1.ext.segtax, "First call should use segtax 7").to.equal(7); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + // Second call with taxonomy 2.2 - should NOT use cache from taxonomy 3.0 + neuwo.getBidRequestData(bidsConfig2, () => {}, conf2, "consent data"); + expect(server.requests.length, "Second call should make a new API request for different taxonomy").to.equal(2); - expect(request.url, "The request URL should not contain a query string").to.include( - encodeURIComponent("https://publisher.works/article.php") + server.requests[1].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) ); - expect(request.url, "The request URL should not contain utm_source").to.not.include( - encodeURIComponent("utm_source") + + // Verify second call has content under segtax 6 (taxonomy 2.2) + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData2, "Second call should have content data").to.exist; + expect(contentData2.ext.segtax, "Second call should use segtax 6").to.equal(6); + }); + + it("should not share cache between different iabTaxonomyFilters values", function () { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf1 = configV1(); + conf1.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf1.params.enableCache = true; + conf1.params.iabTaxonomyFilters = { ContentTier1: { limit: 1 } }; + + const conf2 = configV1(); + conf2.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf2.params.enableCache = true; + // No filters + + // First call with filters + neuwo.getBidRequestData(bidsConfig1, () => {}, conf1, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); + + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) ); + + // Second call without filters - should NOT reuse filtered cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf2, "consent data"); + expect(server.requests.length, "Second call should make a new API request for different filters").to.equal(2); }); - it("should leave URL unchanged if specified params do not exist", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - const originalUrl = "https://publisher.works/article.php?id=5"; - conf.params.websiteToAnalyseUrl = originalUrl; - conf.params.stripQueryParams = ["utm_source", "nonexistent"]; + it("should share cache when legacy config is identical", function () { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf = configV1(); + conf.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf.params.enableCache = true; - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + // First call + neuwo.getBidRequestData(bidsConfig1, () => {}, conf, "consent data"); + expect(server.requests.length, "First call should make an API request").to.equal(1); - expect(request.url, "The request URL should contain the original URL").to.include( - encodeURIComponent(originalUrl) + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) ); - }); - }); - describe("when no stripping options are provided", function () { - it("should send the URL with all query parameters intact", function () { - const bidsConfig = bidsConfiglike(); - const conf = config(); - const originalUrl = "https://publisher.works/article.php?get=horrible_url_for_testing&id=5"; - conf.params.websiteToAnalyseUrl = originalUrl; + // Second call with same config - should use cache + neuwo.getBidRequestData(bidsConfig2, () => {}, conf, "consent data"); + expect(server.requests.length, "Second call should use cache for identical config").to.equal(1); - neuwo.getBidRequestData(bidsConfig, () => {}, conf, "consent data"); - const request = server.requests[0]; + const contentData1 = bidsConfig1.ortb2Fragments.global?.site?.content?.data?.[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData1, "First call should have content data").to.exist; + expect(contentData2, "Second call should have content data from cache").to.exist; + expect(contentData1.segment, "Cached data should match original").to.deep.equal(contentData2.segment); + }); - expect(request.url, "The request URL should contain the full original URL").to.include( - encodeURIComponent(originalUrl) + it("should not share pending requests between different taxonomy versions", function (done) { + const apiResponse = getNeuwoApiResponseV1(); + const bidsConfig1 = bidsConfiglike(); + const bidsConfig2 = bidsConfiglike(); + const conf1 = configV1(); + conf1.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf1.params.enableCache = true; + conf1.params.iabContentTaxonomyVersion = "3.0"; + + const conf2 = configV1(); + conf2.params.websiteToAnalyseUrl = "https://publisher.works/same-page"; + conf2.params.enableCache = true; + conf2.params.iabContentTaxonomyVersion = "2.2"; + + let callbackCount = 0; + const callback = () => { + callbackCount++; + if (callbackCount === 2) { + try { + // Both should have made separate API requests + expect(server.requests.length, "Should make two API requests for different taxonomies").to.equal(2); + + const contentData1 = bidsConfig1.ortb2Fragments.global?.site?.content?.data?.[0]; + const contentData2 = bidsConfig2.ortb2Fragments.global?.site?.content?.data?.[0]; + expect(contentData1, "First call should have content data").to.exist; + expect(contentData2, "Second call should have content data").to.exist; + expect(contentData1.ext.segtax, "First call should use segtax 7").to.equal(7); + expect(contentData2.ext.segtax, "Second call should use segtax 6").to.equal(6); + done(); + } catch (e) { + done(e); + } + } + }; + + // Two concurrent calls with different taxonomy versions + neuwo.getBidRequestData(bidsConfig1, callback, conf1, "consent data"); + neuwo.getBidRequestData(bidsConfig2, callback, conf2, "consent data"); + + // Should be two separate requests, not shared pending promise + expect(server.requests.length, "Should make two separate API requests").to.equal(2); + + server.requests[0].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) + ); + server.requests[1].respond( + 200, + { "Content-Type": "application/json; encoding=UTF-8" }, + JSON.stringify(apiResponse) ); }); }); diff --git a/test/spec/modules/newspassidBidAdapter_spec.js b/test/spec/modules/newspassidBidAdapter_spec.js index b1668aafe17..e8f3fe176f0 100644 --- a/test/spec/modules/newspassidBidAdapter_spec.js +++ b/test/spec/modules/newspassidBidAdapter_spec.js @@ -161,13 +161,13 @@ describe('newspassidBidAdapter', function () { describe('interpretResponse', function() { it('should return empty array if no valid bids', function() { - const invalidResponse = {body: {}}; + const invalidResponse = { body: {} }; const bids = spec.interpretResponse(invalidResponse); expect(bids).to.be.empty; }); it('should return empty array if no seatbid', function() { - const noSeatbidResponse = {body: {cur: 'USD'}}; + const noSeatbidResponse = { body: { cur: 'USD' } }; const bids = spec.interpretResponse(noSeatbidResponse); expect(bids).to.be.empty; }); @@ -198,24 +198,24 @@ describe('newspassidBidAdapter', function () { }); it('should expect correct host', function() { - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', {}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], {}, '', {}); const url = new URL(syncs[0].url); expect(url.host).to.equal('npid.amspbs.com'); }); it('should expect correct pathname', function() { - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', {}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], {}, '', {}); const url = new URL(syncs[0].url); expect(url.pathname).to.equal('/v0/user/sync'); }); it('should return empty array when iframe sync option is disabled', function() { - const syncs = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(syncs).to.be.empty; }); it('should use iframe sync when iframe enabled', function() { - const syncs = spec.getUserSyncs({iframeEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); expect(syncs).to.have.lengthOf(1); expect(syncs[0].type).to.equal('iframe'); expect(syncs[0].url).to.equal('https://npid.amspbs.com/v0/user/sync?gdpr=0&gdpr_consent=&gpp=&gpp_sid=&us_privacy='); @@ -234,7 +234,7 @@ describe('newspassidBidAdapter', function () { } } }; - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], gdprConsent); const url = new URL(syncs[0].url); expect(url.searchParams.get('gdpr')).to.equal('1'); expect(url.searchParams.get('gdpr_consent')).to.equal(encodeURIComponent(consentString)); @@ -253,13 +253,13 @@ describe('newspassidBidAdapter', function () { } } }; - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], gdprConsent); expect(syncs).to.be.empty; }); it('should include correct us_privacy param', function() { const uspConsent = '1YNN'; - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, uspConsent, {}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], {}, uspConsent, {}); const url = new URL(syncs[0].url); expect(url.searchParams.get('gdpr')).to.equal('0'); expect(url.searchParams.get('gdpr_consent')).to.equal(''); @@ -276,7 +276,7 @@ describe('newspassidBidAdapter', function () { gppString: gppConsentString, applicableSections: gppSections }; - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], {}, '', gppConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], {}, '', gppConsent); const url = new URL(syncs[0].url); expect(url.searchParams.get('gdpr')).to.equal('0'); expect(url.searchParams.get('gdpr_consent')).to.equal(''); @@ -291,7 +291,7 @@ describe('newspassidBidAdapter', function () { publisherId: TEST_PUBLISHER_ID } }); - const syncs = spec.getUserSyncs({iframeEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); const url = new URL(syncs[0].url); expect(url.searchParams.get('gdpr')).to.equal('0'); expect(url.searchParams.get('gdpr_consent')).to.equal(''); @@ -302,8 +302,8 @@ describe('newspassidBidAdapter', function () { }); it('should have zero user syncs if coppa is true', function() { - config.setConfig({coppa: true}); - const syncs = spec.getUserSyncs({iframeEnabled: true}); + config.setConfig({ coppa: true }); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); expect(syncs).to.be.empty; }); @@ -333,7 +333,7 @@ describe('newspassidBidAdapter', function () { publisherId: TEST_PUBLISHER_ID } }); - const syncs = spec.getUserSyncs({iframeEnabled: true}, [], gdprConsent, uspConsent, gppConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, [], gdprConsent, uspConsent, gppConsent); const url = new URL(syncs[0].url); expect(url.searchParams.get('gdpr')).to.equal('1'); expect(url.searchParams.get('gdpr_consent')).to.equal(encodeURIComponent(consentString)); diff --git a/test/spec/modules/nextMillenniumBidAdapter_spec.js b/test/spec/modules/nextMillenniumBidAdapter_spec.js index e05d797526a..f5f1cf76ab1 100644 --- a/test/spec/modules/nextMillenniumBidAdapter_spec.js +++ b/test/spec/modules/nextMillenniumBidAdapter_spec.js @@ -21,14 +21,14 @@ describe('nextMillenniumBidAdapterTests', () => { impId: '5', id: '123', bid: { - mediaTypes: {banner: {sizes: [[300, 250], [320, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [320, 250]] } }, adUnitCode: 'test-banner-1', bidId: 'e36ea395f67f', }, mediaTypes: { banner: { - data: {sizes: [[300, 250], [320, 250]]}, + data: { sizes: [[300, 250], [320, 250]] }, bidfloorcur: 'EUR', bidfloor: 1.11, pos: 3, @@ -40,12 +40,12 @@ describe('nextMillenniumBidAdapterTests', () => { id: '5', bidfloorcur: 'EUR', bidfloor: 1.11, - ext: {prebid: {storedrequest: {id: '123'}}}, + ext: { prebid: { storedrequest: { id: '123' } } }, banner: { pos: 3, w: 300, h: 250, - format: [{w: 300, h: 250}, {w: 320, h: 250}], + format: [{ w: 300, h: 250 }, { w: 320, h: 250 }], }, }, }, @@ -56,14 +56,14 @@ describe('nextMillenniumBidAdapterTests', () => { impId: '3', id: '234', bid: { - mediaTypes: {video: {playerSize: [400, 300], api: [2], placement: 1, plcmt: 1}}, + mediaTypes: { video: { playerSize: [400, 300], api: [2], placement: 1, plcmt: 1 } }, adUnitCode: 'test-video-1', bidId: 'e36ea395f67f', }, mediaTypes: { video: { - data: {playerSize: [400, 300], api: [2], placement: 1, plcmt: 1}, + data: { playerSize: [400, 300], api: [2], placement: 1, plcmt: 1 }, bidfloorcur: 'USD', pos: 0, }, @@ -73,7 +73,7 @@ describe('nextMillenniumBidAdapterTests', () => { expected: { id: '3', bidfloorcur: 'USD', - ext: {prebid: {storedrequest: {id: '234'}}}, + ext: { prebid: { storedrequest: { id: '234' } } }, video: { mimes: ['video/mp4', 'video/x-ms-wmv', 'application/javascript'], api: [2], @@ -92,13 +92,13 @@ describe('nextMillenniumBidAdapterTests', () => { impId: '4', id: '234', bid: { - mediaTypes: {video: {w: 640, h: 480}}, + mediaTypes: { video: { w: 640, h: 480 } }, bidId: 'e36ea395f67f', }, mediaTypes: { video: { - data: {w: 640, h: 480}, + data: { w: 640, h: 480 }, bidfloorcur: 'USD', }, }, @@ -107,8 +107,8 @@ describe('nextMillenniumBidAdapterTests', () => { expected: { id: '4', bidfloorcur: 'USD', - ext: {prebid: {storedrequest: {id: '234'}}}, - video: {w: 640, h: 480, mimes: ['video/mp4', 'video/x-ms-wmv', 'application/javascript']}, + ext: { prebid: { storedrequest: { id: '234' } } }, + video: { w: 640, h: 480, mimes: ['video/mp4', 'video/x-ms-wmv', 'application/javascript'] }, }, }, @@ -118,15 +118,15 @@ describe('nextMillenniumBidAdapterTests', () => { impId: '2', id: '123', bid: { - mediaTypes: {banner: {sizes: [[300, 250], [320, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [320, 250]] } }, adUnitCode: 'test-gpid-1', bidId: 'e36ea395f67a', - ortb2Imp: {ext: {gpid: 'imp-gpid-123'}}, + ortb2Imp: { ext: { gpid: 'imp-gpid-123' } }, }, mediaTypes: { banner: { - data: {sizes: [[300, 250], [320, 250]]}, + data: { sizes: [[300, 250], [320, 250]] }, }, }, }, @@ -134,10 +134,10 @@ describe('nextMillenniumBidAdapterTests', () => { expected: { id: '2', ext: { - prebid: {storedrequest: {id: '123'}}, + prebid: { storedrequest: { id: '123' } }, gpid: 'imp-gpid-123' }, - banner: {w: 300, h: 250, format: [{w: 300, h: 250}, {w: 320, h: 250}]}, + banner: { w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 320, h: 250 }] }, }, }, @@ -147,7 +147,7 @@ describe('nextMillenniumBidAdapterTests', () => { impId: '1', id: '123', bid: { - mediaTypes: {banner: {sizes: [[300, 250], [320, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250], [320, 250]] } }, adUnitCode: 'test-gpid-1', bidId: 'e36ea395f67a', ortb2Imp: { @@ -161,7 +161,7 @@ describe('nextMillenniumBidAdapterTests', () => { mediaTypes: { banner: { - data: {sizes: [[300, 250], [320, 250]]}, + data: { sizes: [[300, 250], [320, 250]] }, }, }, }, @@ -169,16 +169,16 @@ describe('nextMillenniumBidAdapterTests', () => { expected: { id: '1', ext: { - prebid: {storedrequest: {id: '123'}}, + prebid: { storedrequest: { id: '123' } }, }, - banner: {w: 300, h: 250, format: [{w: 300, h: 250}, {w: 320, h: 250}]}, + banner: { w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 320, h: 250 }] }, }, }, ]; - for (const {title, data, expected} of dataTests) { + for (const { title, data, expected } of dataTests) { it(title, () => { - const {impId, bid, id, mediaTypes} = data; + const { impId, bid, id, mediaTypes } = data; const imp = getImp(impId, bid, id, mediaTypes); expect(imp).to.deep.equal(expected); }); @@ -190,13 +190,13 @@ describe('nextMillenniumBidAdapterTests', () => { { title: 'position is - 1', pos: 0, - expected: {pos: 0}, + expected: { pos: 0 }, }, { title: 'position is - 2', pos: 7, - expected: {pos: 7}, + expected: { pos: 7 }, }, { @@ -205,7 +205,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, pos, expected} of tests) { + for (const { title, pos, expected } of tests) { it(title, () => { const obj = {}; setImpPos(obj, pos); @@ -235,7 +235,7 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, @@ -249,7 +249,7 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, @@ -265,7 +265,7 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, @@ -279,7 +279,7 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, @@ -296,7 +296,7 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, @@ -311,14 +311,14 @@ describe('nextMillenniumBidAdapterTests', () => { config: { ver: '1.0', complete: 1, - nodes: [{asi: 'test.test', sid: '00001', hp: 1}], + nodes: [{ asi: 'test.test', sid: '00001', hp: 1 }], }, }, }, }, ]; - for (const {title, validBidRequests, bidderRequest, expected} of dataTests) { + for (const { title, validBidRequests, bidderRequest, expected } of dataTests) { it(title, () => { const source = getSourceObj(validBidRequests, bidderRequest); expect(source).to.deep.equal(expected); @@ -334,14 +334,14 @@ describe('nextMillenniumBidAdapterTests', () => { postBody: {}, bidderRequest: { uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, - ortb2: {regs: {gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10], coppa: 1}}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, + ortb2: { regs: { gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10], coppa: 1 } }, }, }, expected: { - user: {consent: 'kjfdniwjnifwenrif3'}, + user: { consent: 'kjfdniwjnifwenrif3' }, regs: { gpp: 'DBACNYA~CPXxRfAPXxR', gpp_sid: [7], @@ -357,13 +357,13 @@ describe('nextMillenniumBidAdapterTests', () => { data: { postBody: {}, bidderRequest: { - gdprConsent: {consentString: 'ewtewbefbawyadexv', gdprApplies: false}, - ortb2: {regs: {gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10], coppa: 0}}, + gdprConsent: { consentString: 'ewtewbefbawyadexv', gdprApplies: false }, + ortb2: { regs: { gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10], coppa: 0 } }, }, }, expected: { - user: {consent: 'ewtewbefbawyadexv'}, + user: { consent: 'ewtewbefbawyadexv' }, regs: { gpp: 'DSFHFHWEUYVDC', gpp_sid: [8, 9, 10], @@ -377,11 +377,11 @@ describe('nextMillenniumBidAdapterTests', () => { title: 'gdprConsent(false)', data: { postBody: {}, - bidderRequest: {gdprConsent: {gdprApplies: false}}, + bidderRequest: { gdprConsent: { gdprApplies: false } }, }, expected: { - regs: {gdpr: 0}, + regs: { gdpr: 0 }, }, }, @@ -396,9 +396,9 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, data, expected} of dataTests) { + for (const { title, data, expected } of dataTests) { it(title, () => { - const {postBody, bidderRequest} = data; + const { postBody, bidderRequest } = data; setConsentStrings(postBody, bidderRequest); expect(postBody).to.deep.equal(expected); }); @@ -412,8 +412,8 @@ describe('nextMillenniumBidAdapterTests', () => { data: { url: 'https://some.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}&type={{.TYPE_PIXEL}}', uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, type: 'image', }, @@ -425,8 +425,8 @@ describe('nextMillenniumBidAdapterTests', () => { data: { url: 'https://some.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&type={{.TYPE_PIXEL}}', uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: false}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: false }, type: 'iframe', }, @@ -438,8 +438,8 @@ describe('nextMillenniumBidAdapterTests', () => { data: { url: 'https://some.url?param1=value1¶m2=value2', uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: false}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: false }, type: 'iframe', }, @@ -456,9 +456,9 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, data, expected} of dataTests) { + for (const { title, data, expected } of dataTests) { it(title, () => { - const {url, gdprConsent, uspConsent, gppConsent, type} = data; + const { url, gdprConsent, uspConsent, gppConsent, type } = data; const newUrl = replaceUsersyncMacros(url, gdprConsent, uspConsent, gppConsent, type); expect(newUrl).to.equal(expected); }); @@ -470,159 +470,189 @@ describe('nextMillenniumBidAdapterTests', () => { { title: 'pixels from responses ({iframeEnabled: true, pixelEnabled: true})', data: { - syncOptions: {iframeEnabled: true, pixelEnabled: true}, + syncOptions: { iframeEnabled: true, pixelEnabled: true }, responses: [ - {body: {ext: {sync: { - image: [ - 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.3.url?param=1234', - ], - - iframe: [ - 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', - ], - }}}}, + { + body: { + ext: { + sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + } + } + } + }, - {body: {ext: {sync: { - iframe: [ - 'https://some.6.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.7.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', - ], - }}}}, + { + body: { + ext: { + sync: { + iframe: [ + 'https://some.6.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.7.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + } + } + } + }, - {body: {ext: {sync: { - image: [ - 'https://some.8.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - ], - }}}}, + { + body: { + ext: { + sync: { + image: [ + 'https://some.8.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + ], + } + } + } + }, ], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [ - {type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'image', url: 'https://some.3.url?param=1234'}, - {type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, - {type: 'iframe', url: 'https://some.6.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'iframe', url: 'https://some.7.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, - {type: 'image', url: 'https://some.8.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, + { type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'image', url: 'https://some.3.url?param=1234' }, + { type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---' }, + { type: 'iframe', url: 'https://some.6.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'iframe', url: 'https://some.7.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---' }, + { type: 'image', url: 'https://some.8.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, ], }, { title: 'pixels from responses ({iframeEnabled: true, pixelEnabled: false})', data: { - syncOptions: {iframeEnabled: true, pixelEnabled: false}, + syncOptions: { iframeEnabled: true, pixelEnabled: false }, responses: [ - {body: {ext: {sync: { - image: [ - 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.3.url?param=1234', - ], - - iframe: [ - 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', - ], - }}}}, + { + body: { + ext: { + sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + } + } + } + }, ], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [ - {type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---'}, + { type: 'iframe', url: 'https://some.4.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'iframe', url: 'https://some.5.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---' }, ], }, { title: 'pixels from responses ({iframeEnabled: false, pixelEnabled: true})', data: { - syncOptions: {iframeEnabled: false, pixelEnabled: true}, + syncOptions: { iframeEnabled: false, pixelEnabled: true }, responses: [ - {body: {ext: {sync: { - image: [ - 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.3.url?param=1234', - ], - - iframe: [ - 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', - 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', - ], - }}}}, + { + body: { + ext: { + sync: { + image: [ + 'https://some.1.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.2.url?us_privacy={{.USPrivacy}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.3.url?param=1234', + ], + + iframe: [ + 'https://some.4.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&gpp={{.GPP}}&gpp_sid={{.GPPSID}}', + 'https://some.5.url?gdpr={{.GDPR}}&gdpr_consent={{.GDPRConsent}}&us_privacy={{.USPrivacy}}', + ], + } + } + } + }, ], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [ - {type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8'}, - {type: 'image', url: 'https://some.3.url?param=1234'}, + { type: 'image', url: 'https://some.1.url?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'image', url: 'https://some.2.url?us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8' }, + { type: 'image', url: 'https://some.3.url?param=1234' }, ], }, { title: 'pixels - responses is empty ({iframeEnabled: true, pixelEnabled: true})', data: { - syncOptions: {iframeEnabled: true, pixelEnabled: true}, + syncOptions: { iframeEnabled: true, pixelEnabled: true }, responses: [], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [ - {type: 'image', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=image'}, - {type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe'}, + { type: 'image', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=image' }, + { type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe' }, ], }, { title: 'pixels - responses is empty ({iframeEnabled: true, pixelEnabled: false})', data: { - syncOptions: {iframeEnabled: true, pixelEnabled: false}, + syncOptions: { iframeEnabled: true, pixelEnabled: false }, uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [ - {type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe'}, + { type: 'iframe', url: 'https://cookies.nextmillmedia.com/sync?gdpr=1&gdpr_consent=kjfdniwjnifwenrif3&us_privacy=1---&gpp=DBACNYA~CPXxRfAPXxR&gpp_sid=7,8&type=iframe' }, ], }, { title: 'pixels - responses is empty ({iframeEnabled: false, pixelEnabled: false})', data: { - syncOptions: {iframeEnabled: false, pixelEnabled: false}, + syncOptions: { iframeEnabled: false, pixelEnabled: false }, uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8]}, - gdprConsent: {consentString: 'kjfdniwjnifwenrif3', gdprApplies: true}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7, 8] }, + gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true }, }, expected: [], }, ]; - for (const {title, data, expected} of dataTests) { + for (const { title, data, expected } of dataTests) { it(title, () => { - const {syncOptions, responses, gdprConsent, uspConsent, gppConsent} = data; + const { syncOptions, responses, gdprConsent, uspConsent, gppConsent } = data; const pixels = spec.getUserSyncs(syncOptions, responses, gdprConsent, uspConsent, gppConsent); expect(pixels).to.deep.equal(expected); }); @@ -642,7 +672,7 @@ describe('nextMillenniumBidAdapterTests', () => { wlangb: ['en', 'fr', 'de'], site: { pagecat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], - content: {cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN'}, + content: { cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN' }, } }, }, @@ -653,7 +683,7 @@ describe('nextMillenniumBidAdapterTests', () => { wlang: ['en', 'fr', 'de'], site: { pagecat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], - content: {cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN'}, + content: { cat: ['IAB2-11', 'IAB2-12', 'IAB2-14'], language: 'EN' }, } }, }, @@ -664,20 +694,20 @@ describe('nextMillenniumBidAdapterTests', () => { postBody: {}, ortb2: { wlangb: ['en', 'fr', 'de'], - user: {keywords: 'key7,key8,key9'}, + user: { keywords: 'key7,key8,key9' }, site: { keywords: 'key1,key2,key3', - content: {keywords: 'key4,key5,key6'}, + content: { keywords: 'key4,key5,key6' }, }, }, }, expected: { wlangb: ['en', 'fr', 'de'], - user: {keywords: 'key7,key8,key9'}, + user: { keywords: 'key7,key8,key9' }, site: { keywords: 'key1,key2,key3', - content: {keywords: 'key4,key5,key6'}, + content: { keywords: 'key4,key5,key6' }, }, }, }, @@ -685,31 +715,35 @@ describe('nextMillenniumBidAdapterTests', () => { { title: 'only site.content.language', data: { - postBody: {site: {domain: 'some.domain'}}, - ortb2: {site: { - content: {language: 'EN'}, - }}, + postBody: { site: { domain: 'some.domain' } }, + ortb2: { + site: { + content: { language: 'EN' }, + } + }, }, - expected: {site: { - domain: 'some.domain', - content: {language: 'EN'}, - }}, + expected: { + site: { + domain: 'some.domain', + content: { language: 'EN' }, + } + }, }, { title: 'object ortb2 is empty', data: { - postBody: {imp: []}, + postBody: { imp: [] }, }, - expected: {imp: []}, + expected: { imp: [] }, }, ]; - for (const {title, data, expected} of dataTests) { + for (const { title, data, expected } of dataTests) { it(title, () => { - const {postBody, ortb2} = data; + const { postBody, ortb2 } = data; setOrtb2Parameters(ALLOWED_ORTB2_PARAMETERS, postBody, ortb2); expect(postBody).to.deep.equal(expected); }); @@ -755,12 +789,12 @@ describe('nextMillenniumBidAdapterTests', () => { userIdAsEids: [ { source: '33across.com', - uids: [{id: 'some-random-id-value', atype: 1}], + uids: [{ id: 'some-random-id-value', atype: 1 }], }, { source: 'utiq.com', - uids: [{id: 'some-random-id-value', atype: 1}], + uids: [{ id: 'some-random-id-value', atype: 1 }], }, ], }, @@ -769,7 +803,7 @@ describe('nextMillenniumBidAdapterTests', () => { userIdAsEids: [ { source: 'test.test', - uids: [{id: 'some-random-id-value', atype: 1}], + uids: [{ id: 'some-random-id-value', atype: 1 }], }, ], }, @@ -781,12 +815,12 @@ describe('nextMillenniumBidAdapterTests', () => { eids: [ { source: '33across.com', - uids: [{id: 'some-random-id-value', atype: 1}], + uids: [{ id: 'some-random-id-value', atype: 1 }], }, { source: 'utiq.com', - uids: [{id: 'some-random-id-value', atype: 1}], + uids: [{ id: 'some-random-id-value', atype: 1 }], }, ], }, @@ -901,17 +935,17 @@ describe('nextMillenniumBidAdapterTests', () => { const expectedNextMilImps = [ { impId: '1', - nextMillennium: {refresh_count: 1}, + nextMillennium: { refresh_count: 1 }, }, { impId: '2', - nextMillennium: {refresh_count: 1}, + nextMillennium: { refresh_count: 1 }, }, { impId: '3', - nextMillennium: {refresh_count: 1}, + nextMillennium: { refresh_count: 1 }, }, ]; @@ -936,7 +970,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidRequested', bids: { bidderCode: 'appnexus', - bids: [{bidder: 'appnexus', params: {}}], + bids: [{ bidder: 'appnexus', params: {} }], }, expected: undefined, @@ -947,7 +981,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidRequested', bids: { bidderCode: 'appnexus', - bids: [{bidder: 'appnexus', params: {placement_id: '807'}}], + bids: [{ bidder: 'appnexus', params: { placement_id: '807' } }], }, expected: undefined, @@ -958,7 +992,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidRequested', bids: { bidderCode: 'nextMillennium', - bids: [{bidder: 'nextMillennium', params: {placement_id: '807'}}], + bids: [{ bidder: 'nextMillennium', params: { placement_id: '807' } }], }, expected: 'https://hb-analytics.nextmillmedia.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&placements=807', @@ -970,8 +1004,8 @@ describe('nextMillenniumBidAdapterTests', () => { bids: { bidderCode: 'nextMillennium', bids: [ - {bidder: 'nextMillennium', params: {placement_id: '807'}}, - {bidder: 'nextMillennium', params: {placement_id: '111'}}, + { bidder: 'nextMillennium', params: { placement_id: '807' } }, + { bidder: 'nextMillennium', params: { placement_id: '111' } }, ], }, @@ -983,7 +1017,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidRequested', bids: { bidderCode: 'nextMillennium', - bids: [{bidder: 'nextMillennium', params: {placement_id: '807', group_id: '123'}}], + bids: [{ bidder: 'nextMillennium', params: { placement_id: '807', group_id: '123' } }], }, expected: 'https://hb-analytics.nextmillmedia.com/statistics/metric?event=bidRequested&bidder=nextMillennium&source=pbjs&groups=123', @@ -995,9 +1029,9 @@ describe('nextMillenniumBidAdapterTests', () => { bids: { bidderCode: 'nextMillennium', bids: [ - {bidder: 'nextMillennium', params: {placement_id: '807', group_id: '123'}}, - {bidder: 'nextMillennium', params: {group_id: '456'}}, - {bidder: 'nextMillennium', params: {placement_id: '222'}}, + { bidder: 'nextMillennium', params: { placement_id: '807', group_id: '123' } }, + { bidder: 'nextMillennium', params: { group_id: '456' } }, + { bidder: 'nextMillennium', params: { placement_id: '222' } }, ], }, @@ -1019,7 +1053,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidResponse', bids: { bidderCode: 'nextMillennium', - params: {placement_id: '807'}, + params: { placement_id: '807' }, }, expected: 'https://hb-analytics.nextmillmedia.com/statistics/metric?event=bidResponse&bidder=nextMillennium&source=pbjs&placements=807', @@ -1040,7 +1074,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'noBid', bids: { bidder: 'nextMillennium', - params: {placement_id: '807'}, + params: { placement_id: '807' }, }, expected: 'https://hb-analytics.nextmillmedia.com/statistics/metric?event=noBid&bidder=nextMillennium&source=pbjs&placements=807', @@ -1061,7 +1095,7 @@ describe('nextMillenniumBidAdapterTests', () => { eventName: 'bidTimeout', bids: { bidder: 'nextMillennium', - params: {placement_id: '807'}, + params: { placement_id: '807' }, }, expected: 'https://hb-analytics.nextmillmedia.com/statistics/metric?event=bidTimeout&bidder=nextMillennium&source=pbjs&placements=807', @@ -1074,20 +1108,20 @@ describe('nextMillenniumBidAdapterTests', () => { { bidderCode: 'nextMillennium', bids: [ - {bidder: 'nextMillennium', params: {placement_id: '807', group_id: '123'}}, - {bidder: 'nextMillennium', params: {group_id: '456'}}, - {bidder: 'nextMillennium', params: {placement_id: '222'}}, + { bidder: 'nextMillennium', params: { placement_id: '807', group_id: '123' } }, + { bidder: 'nextMillennium', params: { group_id: '456' } }, + { bidder: 'nextMillennium', params: { placement_id: '222' } }, ], }, { bidderCode: 'nextMillennium', - params: {group_id: '7777'}, + params: { group_id: '7777' }, }, { bidderCode: 'nextMillennium', - params: {placement_id: '8888'}, + params: { placement_id: '8888' }, }, ], @@ -1095,7 +1129,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, eventName, bids, expected} of dataForTests) { + for (const { title, eventName, bids, expected } of dataForTests) { it(title, () => { const url = spec._getUrlPixelMetric(eventName, bids); expect(url).to.equal(expected); @@ -1107,7 +1141,7 @@ describe('nextMillenniumBidAdapterTests', () => { const tests = [ { title: 'test - 1', - bidderRequest: {bidderRequestId: 'mock-uuid', timeout: 1200}, + bidderRequest: { bidderRequestId: 'mock-uuid', timeout: 1200 }, bidRequests: [ { adUnitCode: 'test-div', @@ -1117,7 +1151,7 @@ describe('nextMillenniumBidAdapterTests', () => { params: { placement_id: '-1' }, sizes: [[300, 250]], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7]}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7] }, gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true @@ -1144,7 +1178,7 @@ describe('nextMillenniumBidAdapterTests', () => { params: { placement_id: '333' }, sizes: [[300, 250]], uspConsent: '1---', - gppConsent: {gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7]}, + gppConsent: { gppString: 'DBACNYA~CPXxRfAPXxR', applicableSections: [7] }, gdprConsent: { consentString: 'kjfdniwjnifwenrif3', gdprApplies: true @@ -1174,7 +1208,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, bidRequests, bidderRequest, expected} of tests) { + for (const { title, bidRequests, bidderRequest, expected } of tests) { it(title, () => { const request = spec.buildRequests(bidRequests, bidderRequest); expect(request.length).to.equal(expected.requestSize); @@ -1223,7 +1257,7 @@ describe('nextMillenniumBidAdapterTests', () => { adomain: ['test.addomain.com'], w: 400, h: 300, - ext: {prebid: {type: 'video'}}, + ext: { prebid: { type: 'video' } }, }, { @@ -1235,7 +1269,7 @@ describe('nextMillenniumBidAdapterTests', () => { adomain: ['test.addomain.com'], w: 640, h: 480, - ext: {prebid: {type: 'video'}}, + ext: { prebid: { type: 'video' } }, }, ], }, @@ -1295,7 +1329,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, serverResponse, bidRequest, expected} of tests) { + for (const { title, serverResponse, bidRequest, expected } of tests) { describe(title, () => { const bids = spec.interpretResponse(serverResponse, bidRequest); for (let i = 0; i < bids.length; i++) { @@ -1350,7 +1384,7 @@ describe('nextMillenniumBidAdapterTests', () => { }, ]; - for (const {title, impId, bid, expected} of tests) { + for (const { title, impId, bid, expected } of tests) { it(title, () => { const extNextMilImp = getExtNextMilImp(impId, bid); expect(extNextMilImp.impId).to.deep.equal(expected.impId); diff --git a/test/spec/modules/nextrollBidAdapter_spec.js b/test/spec/modules/nextrollBidAdapter_spec.js index 5838e2929a0..a74bda4e52b 100644 --- a/test/spec/modules/nextrollBidAdapter_spec.js +++ b/test/spec/modules/nextrollBidAdapter_spec.js @@ -36,13 +36,13 @@ describe('nextrollBidAdapter', function() { bidId: 'bid_id', mediaTypes: { native: { - title: {required: true, len: 80}, - image: {required: true, sizes: [728, 90]}, - sponsoredBy: {required: false, len: 20}, - clickUrl: {required: true}, - body: {required: true, len: 25}, - icon: {required: true, sizes: [50, 50], aspect_ratios: [{ratio_height: 3, ratio_width: 4}]}, - someRandomAsset: {required: false, len: 100} // This should be ignored + title: { required: true, len: 80 }, + image: { required: true, sizes: [728, 90] }, + sponsoredBy: { required: false, len: 20 }, + clickUrl: { required: true }, + body: { required: true, len: 25 }, + icon: { required: true, sizes: [50, 50], aspect_ratios: [{ ratio_height: 3, ratio_width: 4 }] }, + someRandomAsset: { required: false, len: 100 } // This should be ignored } }, params: { @@ -56,11 +56,11 @@ describe('nextrollBidAdapter', function() { const assets = request[0].data.imp.native.request.native.assets const excptedAssets = [ - {id: 1, required: 1, title: {len: 80}}, - {id: 2, required: 1, img: {w: 728, h: 90, wmin: 1, hmin: 1, type: 3}}, - {id: 3, required: 1, img: {w: 50, h: 50, wmin: 4, hmin: 3, type: 1}}, - {id: 5, required: 0, data: {len: 20, type: 1}}, - {id: 6, required: 1, data: {len: 25, type: 2}} + { id: 1, required: 1, title: { len: 80 } }, + { id: 2, required: 1, img: { w: 728, h: 90, wmin: 1, hmin: 1, type: 3 } }, + { id: 3, required: 1, img: { w: 50, h: 50, wmin: 4, hmin: 3, type: 1 } }, + { id: 5, required: 0, data: { len: 20, type: 1 } }, + { id: 6, required: 1, data: { len: 25, type: 2 } } ] expect(assets).to.be.deep.equal(excptedAssets) }) @@ -149,7 +149,7 @@ describe('nextrollBidAdapter', function() { it('sets the CCPA consent string', function () { const us_privacy = '1YYY'; - const request = spec.buildRequests([validBid], {'uspConsent': us_privacy})[0]; + const request = spec.buildRequests([validBid], { 'uspConsent': us_privacy })[0]; expect(request.data.regs.ext.us_privacy).to.be.equal(us_privacy); }); @@ -190,11 +190,11 @@ describe('nextrollBidAdapter', function() { }); it('builds the same amount of responses as server responses it receives', function () { - expect(spec.interpretResponse({body: responseBody}, {})).to.be.lengthOf(2); + expect(spec.interpretResponse({ body: responseBody }, {})).to.be.lengthOf(2); }); it('builds a response with the expected fields', function () { - const response = spec.interpretResponse({body: responseBody}, {})[0]; + const response = spec.interpretResponse({ body: responseBody }, {})[0]; expect(response.requestId).to.be.equal('bidresponse_id'); expect(response.cpm).to.be.equal(1.2); @@ -226,11 +226,11 @@ describe('nextrollBidAdapter', function() { price: 1.2, crid: 'crid1', adm: { - link: {url: clickUrl}, + link: { url: clickUrl }, assets: [ - {id: 1, title: {text: titleText}}, - {id: 2, img: {w: imgW, h: imgH, url: imgUrl}}, - {id: 5, data: {value: brandText}} + { id: 1, title: { text: titleText } }, + { id: 2, img: { w: imgW, h: imgH, url: imgUrl } }, + { id: 5, data: { value: brandText } } ], imptrackers: [impUrl] } @@ -247,7 +247,7 @@ describe('nextrollBidAdapter', function() { privacyLink: 'https://app.adroll.com/optout/personalized', privacyIcon: 'https://s.adroll.com/j/ad-choices-small.png', title: titleText, - image: {url: imgUrl, width: imgW, height: imgH}, + image: { url: imgUrl, width: imgW, height: imgH }, sponsoredBy: brandText, clickTrackers: [], jstracker: [] @@ -263,9 +263,9 @@ describe('nextrollBidAdapter', function() { const bodyText = 'Some body text' allAssetsResponse.body.seatbid[0].bid[0].adm.assets.push(...[ - {id: 3, img: {w: iconW, h: iconH, url: iconUrl}}, - {id: 4, img: {w: logoW, h: logoH, url: logoUrl}}, - {id: 6, data: {value: bodyText}} + { id: 3, img: { w: iconW, h: iconH, url: iconUrl } }, + { id: 4, img: { w: logoW, h: logoH, url: logoUrl } }, + { id: 6, data: { value: bodyText } } ]) const response = spec.interpretResponse(allAssetsResponse) @@ -277,9 +277,9 @@ describe('nextrollBidAdapter', function() { privacyLink: 'https://app.adroll.com/optout/personalized', privacyIcon: 'https://s.adroll.com/j/ad-choices-small.png', title: titleText, - image: {url: imgUrl, width: imgW, height: imgH}, - icon: {url: iconUrl, width: iconW, height: iconH}, - logo: {url: logoUrl, width: logoW, height: logoH}, + image: { url: imgUrl, width: imgW, height: imgH }, + icon: { url: iconUrl, width: iconW, height: iconH }, + logo: { url: logoUrl, width: logoW, height: logoH }, body: bodyText, sponsoredBy: brandText } diff --git a/test/spec/modules/nexverseBidAdapter_spec.js b/test/spec/modules/nexverseBidAdapter_spec.js index 63d4046a28e..bb73acba923 100644 --- a/test/spec/modules/nexverseBidAdapter_spec.js +++ b/test/spec/modules/nexverseBidAdapter_spec.js @@ -31,7 +31,7 @@ describe('nexverseBidAdapterTests', () => { it('should return false when valid params are not passed', function () { const bid = Object.assign({}, sbid); delete bid.params; - bid.params = {uid: '', pubId: '', pubEpid: ''}; + bid.params = { uid: '', pubId: '', pubEpid: '' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); @@ -44,7 +44,7 @@ describe('nexverseBidAdapterTests', () => { sizes: [[300, 250]] } }; - bid.params = {uid: '77d4a2eb3d209ce6c7691dc79fcab358', pubId: '24051'}; + bid.params = { uid: '77d4a2eb3d209ce6c7691dc79fcab358', pubId: '24051' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should return true when valid params are passed as nums', function () { @@ -55,7 +55,7 @@ describe('nexverseBidAdapterTests', () => { sizes: [[300, 250]] } }; - bid.params = {uid: '77d4a2eb3d209ce6c7691dc79fcab358', pubId: '24051', pubEpid: '34561'}; + bid.params = { uid: '77d4a2eb3d209ce6c7691dc79fcab358', pubId: '24051', pubEpid: '34561' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); }); diff --git a/test/spec/modules/nexx360BidAdapter_spec.js b/test/spec/modules/nexx360BidAdapter_spec.js index d3ba872946f..f6f5461d361 100644 --- a/test/spec/modules/nexx360BidAdapter_spec.js +++ b/test/spec/modules/nexx360BidAdapter_spec.js @@ -345,7 +345,7 @@ describe('Nexx360 bid adapter tests', () => { source: 'prebid.js', pageViewId: requestContent.ext.pageViewId, bidderVersion: '7.1', - localStorage: { amxId: 'abcdef'}, + localStorage: { amxId: 'abcdef' }, sessionId: requestContent.ext.sessionId, requestCounter: 0, }, @@ -717,7 +717,7 @@ describe('Nexx360 bid adapter tests', () => { }); it('Verifies user sync with cookies in bid response', () => { response.body.ext = { - cookies: [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}] + cookies: [{ 'type': 'image', 'url': 'http://www.cookie.sync.org/' }] }; const syncs = spec.getUserSyncs({}, [response], DEFAULT_OPTIONS.gdprConsent); const expectedSyncs = [{ type: 'image', url: 'http://www.cookie.sync.org/' }]; diff --git a/test/spec/modules/nobidAnalyticsAdapter_spec.js b/test/spec/modules/nobidAnalyticsAdapter_spec.js index e20348f51cc..5b7abf42762 100644 --- a/test/spec/modules/nobidAnalyticsAdapter_spec.js +++ b/test/spec/modules/nobidAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ import nobidAnalytics from 'modules/nobidAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; import { EVENTS } from 'src/constants.js'; const events = require('src/events'); const adapterManager = require('src/adapterManager').default; @@ -46,10 +46,12 @@ describe('NoBid Prebid Analytic', function () { }); // Step 2: Send init auction event - events.emit(EVENTS.AUCTION_INIT, {config: initOptions, + events.emit(EVENTS.AUCTION_INIT, { + config: initOptions, auctionId: '13', timestamp: Date.now(), - bidderRequests: [{refererInfo: {topmostLocation: TOP_LOCATION}}]}); + bidderRequests: [{ refererInfo: { topmostLocation: TOP_LOCATION } }] + }); expect(nobidAnalytics.initOptions).to.have.property('siteId', SITE_ID); expect(nobidAnalytics).to.have.property('topLocation', TOP_LOCATION); @@ -77,10 +79,12 @@ describe('NoBid Prebid Analytic', function () { }); // Step 2: Send init auction event - events.emit(EVENTS.AUCTION_INIT, {config: initOptions, + events.emit(EVENTS.AUCTION_INIT, { + config: initOptions, auctionId: '13', timestamp: Date.now(), - bidderRequests: [{refererInfo: {topmostLocation: TOP_LOCATION}}]}); + bidderRequests: [{ refererInfo: { topmostLocation: TOP_LOCATION } }] + }); events.emit(EVENTS.BID_WON, {}); clock.tick(5000); expect(server.requests).to.have.length(1); @@ -191,10 +195,12 @@ describe('NoBid Prebid Analytic', function () { }); // Step 2: Send init auction event - events.emit(EVENTS.AUCTION_INIT, {config: initOptions, + events.emit(EVENTS.AUCTION_INIT, { + config: initOptions, auctionId: '13', timestamp: Date.now(), - bidderRequests: [{refererInfo: {topmostLocation: TOP_LOCATION}}]}); + bidderRequests: [{ refererInfo: { topmostLocation: TOP_LOCATION } }] + }); // Step 3: Send bid won event events.emit(EVENTS.BID_WON, requestIncoming); @@ -388,10 +394,12 @@ describe('NoBid Prebid Analytic', function () { }); // Step 2: Send init auction event - events.emit(EVENTS.AUCTION_INIT, {config: initOptions, + events.emit(EVENTS.AUCTION_INIT, { + config: initOptions, auctionId: '13', timestamp: Date.now(), - bidderRequests: [{refererInfo: {topmostLocation: `${TOP_LOCATION}_something`}}]}); + bidderRequests: [{ refererInfo: { topmostLocation: `${TOP_LOCATION}_something` } }] + }); // Step 3: Send bid won event events.emit(EVENTS.AUCTION_END, requestIncoming); @@ -426,30 +434,30 @@ describe('NoBid Prebid Analytic', function () { it('Analytics disabled test', function (done) { let disabled; - nobidAnalytics.processServerResponse(JSON.stringify({disabled: 0})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled: 0 })); disabled = nobidAnalytics.isAnalyticsDisabled(); expect(disabled).to.equal(false); - events.emit(EVENTS.AUCTION_END, {auctionId: '1234567890'}); + events.emit(EVENTS.AUCTION_END, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(1); - events.emit(EVENTS.AUCTION_END, {auctionId: '12345678901'}); + events.emit(EVENTS.AUCTION_END, { auctionId: '12345678901' }); clock.tick(1000); expect(server.requests).to.have.length(2); nobidAnalytics.processServerResponse('disabled: true'); - events.emit(EVENTS.AUCTION_END, {auctionId: '12345678902'}); + events.emit(EVENTS.AUCTION_END, { auctionId: '12345678902' }); clock.tick(1000); expect(server.requests).to.have.length(3); - nobidAnalytics.processServerResponse(JSON.stringify({disabled: 1})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled: 1 })); disabled = nobidAnalytics.isAnalyticsDisabled(); expect(disabled).to.equal(true); - events.emit(EVENTS.AUCTION_END, {auctionId: '12345678902'}); + events.emit(EVENTS.AUCTION_END, { auctionId: '12345678902' }); clock.tick(5000); expect(server.requests).to.have.length(3); nobidAnalytics.retentionSeconds = 5; - nobidAnalytics.processServerResponse(JSON.stringify({disabled: 1})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled: 1 })); clock.tick(1000); disabled = nobidAnalytics.isAnalyticsDisabled(); expect(disabled).to.equal(true); @@ -484,32 +492,32 @@ describe('NoBid Prebid Analytic', function () { let eventType = EVENTS.AUCTION_END; let disabled; - nobidAnalytics.processServerResponse(JSON.stringify({disabled: 0})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled: 0 })); disabled = nobidAnalytics.isAnalyticsDisabled(); expect(disabled).to.equal(false); - events.emit(eventType, {auctionId: '1234567890'}); + events.emit(eventType, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(1); - events.emit(eventType, {auctionId: '12345678901'}); + events.emit(eventType, { auctionId: '12345678901' }); clock.tick(1000); expect(server.requests).to.have.length(2); server.requests.length = 0; expect(server.requests).to.have.length(0); - nobidAnalytics.processServerResponse(JSON.stringify({disabled_auctionEnd: 1})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled_auctionEnd: 1 })); disabled = nobidAnalytics.isAnalyticsDisabled(eventType); expect(disabled).to.equal(true); - events.emit(eventType, {auctionId: '1234567890'}); + events.emit(eventType, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(0); server.requests.length = 0; - nobidAnalytics.processServerResponse(JSON.stringify({disabled_auctionEnd: 0})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled_auctionEnd: 0 })); disabled = nobidAnalytics.isAnalyticsDisabled(eventType); expect(disabled).to.equal(false); - events.emit(EVENTS.AUCTION_END, {auctionId: '1234567890'}); + events.emit(EVENTS.AUCTION_END, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(1); @@ -517,10 +525,10 @@ describe('NoBid Prebid Analytic', function () { expect(server.requests).to.have.length(0); eventType = EVENTS.BID_WON; - nobidAnalytics.processServerResponse(JSON.stringify({disabled_bidWon: 1})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled_bidWon: 1 })); disabled = nobidAnalytics.isAnalyticsDisabled(eventType); expect(disabled).to.equal(true); - events.emit(eventType, {bidderCode: 'nobid'}); + events.emit(eventType, { bidderCode: 'nobid' }); clock.tick(1000); expect(server.requests).to.have.length(0); @@ -528,10 +536,10 @@ describe('NoBid Prebid Analytic', function () { expect(server.requests).to.have.length(0); eventType = EVENTS.AUCTION_END; - nobidAnalytics.processServerResponse(JSON.stringify({disabled: 1})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled: 1 })); disabled = nobidAnalytics.isAnalyticsDisabled(eventType); expect(disabled).to.equal(true); - events.emit(eventType, {auctionId: '1234567890'}); + events.emit(eventType, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(0); @@ -539,15 +547,15 @@ describe('NoBid Prebid Analytic', function () { expect(server.requests).to.have.length(0); eventType = EVENTS.AUCTION_END; - nobidAnalytics.processServerResponse(JSON.stringify({disabled_auctionEnd: 1, disabled_bidWon: 0})); + nobidAnalytics.processServerResponse(JSON.stringify({ disabled_auctionEnd: 1, disabled_bidWon: 0 })); disabled = nobidAnalytics.isAnalyticsDisabled(eventType); expect(disabled).to.equal(true); - events.emit(eventType, {auctionId: '1234567890'}); + events.emit(eventType, { auctionId: '1234567890' }); clock.tick(1000); expect(server.requests).to.have.length(0); disabled = nobidAnalytics.isAnalyticsDisabled(EVENTS.BID_WON); expect(disabled).to.equal(false); - events.emit(EVENTS.BID_WON, {bidderCode: 'nobid'}); + events.emit(EVENTS.BID_WON, { bidderCode: 'nobid' }); clock.tick(1000); expect(server.requests).to.have.length(1); @@ -574,17 +582,17 @@ describe('NoBid Prebid Analytic', function () { let active = nobidCarbonizer.isActive(); expect(active).to.equal(false); - nobidAnalytics.processServerResponse(JSON.stringify({carbonizer_active: false})); + nobidAnalytics.processServerResponse(JSON.stringify({ carbonizer_active: false })); active = nobidCarbonizer.isActive(); expect(active).to.equal(false); - nobidAnalytics.processServerResponse(JSON.stringify({carbonizer_active: true})); + nobidAnalytics.processServerResponse(JSON.stringify({ carbonizer_active: true })); active = nobidCarbonizer.isActive(); expect(active).to.equal(true); const previousRetention = nobidAnalytics.retentionSeconds; nobidAnalytics.retentionSeconds = 3; - nobidAnalytics.processServerResponse(JSON.stringify({carbonizer_active: true})); + nobidAnalytics.processServerResponse(JSON.stringify({ carbonizer_active: true })); let stored = nobidCarbonizer.getStoredLocalData(); expect(stored[nobidAnalytics.ANALYTICS_DATA_NAME]).to.contain(`{"carbonizer_active":true,"ts":`); clock.tick(5000); @@ -592,7 +600,7 @@ describe('NoBid Prebid Analytic', function () { expect(active).to.equal(false); nobidAnalytics.retentionSeconds = previousRetention; - nobidAnalytics.processServerResponse(JSON.stringify({carbonizer_active: true})); + nobidAnalytics.processServerResponse(JSON.stringify({ carbonizer_active: true })); active = nobidCarbonizer.isActive(); expect(active).to.equal(true); diff --git a/test/spec/modules/nobidBidAdapter_spec.js b/test/spec/modules/nobidBidAdapter_spec.js index 53a8381216c..4f5034edf6b 100644 --- a/test/spec/modules/nobidBidAdapter_spec.js +++ b/test/spec/modules/nobidBidAdapter_spec.js @@ -33,7 +33,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should FLoor = 1', function () { @@ -98,7 +98,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER}, bidderCode: BIDDER_CODE + refererInfo: { page: REFERER }, bidderCode: BIDDER_CODE } const siteName = 'example'; @@ -116,16 +116,16 @@ describe('Nobid Adapter', function () { site: { name: siteName, domain: siteDomain, - cat: [ siteCat ], - sectioncat: [ siteSectionCat ], - pagecat: [ sitePageCat ], + cat: [siteCat], + sectioncat: [siteSectionCat], + pagecat: [sitePageCat], page: sitePage, ref: siteRef, keywords: siteKeywords, search: siteSearch } }; - const request = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}); + const request = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }); let payload = JSON.parse(request.data); payload = JSON.parse(JSON.stringify(payload)); expect(payload.sid).to.equal(SITE_ID); @@ -163,9 +163,9 @@ describe('Nobid Adapter', function () { const GPP_SID = [1, 3]; const bidderRequest = { - refererInfo: {page: REFERER}, + refererInfo: { page: REFERER }, bidderCode: BIDDER_CODE, - gppConsent: {gppString: GPP, applicableSections: GPP_SID} + gppConsent: { gppString: GPP, applicableSections: GPP_SID } } it('gpp should match', function () { @@ -187,7 +187,7 @@ describe('Nobid Adapter', function () { it('gpp ortb2 should match', function () { delete bidderRequest.gppConsent; - bidderRequest.ortb2 = {regs: {gpp: GPP, gpp_sid: GPP_SID}}; + bidderRequest.ortb2 = { regs: { gpp: GPP, gpp_sid: GPP_SID } }; const request = spec.buildRequests(bidRequests, bidderRequest); let payload = JSON.parse(request.data); payload = JSON.parse(JSON.stringify(payload)); @@ -215,7 +215,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER}, bidderCode: BIDDER_CODE + refererInfo: { page: REFERER }, bidderCode: BIDDER_CODE } it('should add source and version to the tag', function () { @@ -389,7 +389,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should add source and version to the tag', function () { @@ -479,7 +479,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should add source and version to the tag', function () { @@ -565,7 +565,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should criteo eid', function () { @@ -599,7 +599,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should add source and version to the tag', function () { @@ -733,7 +733,7 @@ describe('Nobid Adapter', function () { ]; const bidderRequest = { - refererInfo: {page: REFERER} + refererInfo: { page: REFERER } } it('should refreshCount = 4', function () { @@ -761,12 +761,13 @@ describe('Nobid Adapter', function () { device: 'COMPUTER', site: 2, bids: [ - {id: 1, + { + id: 1, bdrid: 101, divid: ADUNIT_300x250, dealid: DEAL_ID, creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, + size: { 'w': 300, 'h': 250 }, adm: ADMARKUP_300x250, price: '' + PRICE_300x250 } @@ -796,7 +797,7 @@ describe('Nobid Adapter', function () { adUnitCode: ADUNIT_300x250 }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); expect(result.length).to.equal(expectedResponse.length); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); expect(result[0].requestId).to.equal(expectedResponse[0].requestId); @@ -810,7 +811,7 @@ describe('Nobid Adapter', function () { adUnitCode: ADUNIT_300x250 + '1' }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); expect(result.length).to.equal(0); }); @@ -837,7 +838,7 @@ describe('Nobid Adapter', function () { adUnitCode: ADUNIT_300x250 }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); expect(result.length).to.equal(expectedResponse.length); expect(result[0].dealId).to.equal(expectedResponse[0].dealId); }); @@ -858,12 +859,13 @@ describe('Nobid Adapter', function () { site: 2, rlimit: REFRESH_LIMIT, bids: [ - {id: 1, + { + id: 1, bdrid: 101, divid: ADUNIT_300x250, dealid: DEAL_ID, creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, + size: { 'w': 300, 'h': 250 }, adm: ADMARKUP_300x250, price: '' + PRICE_300x250 } @@ -877,7 +879,7 @@ describe('Nobid Adapter', function () { adUnitCode: ADUNIT_300x250 }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); expect(nobid.refreshLimit).to.equal(REFRESH_LIMIT); }); }); @@ -896,12 +898,13 @@ describe('Nobid Adapter', function () { device: 'COMPUTER', site: 2, bids: [ - {id: 1, + { + id: 1, bdrid: 101, divid: ADUNIT_300x250, dealid: DEAL_ID, creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, + size: { 'w': 300, 'h': 250 }, adm: ADMARKUP_300x250, price: '' + PRICE_300x250, meta: { @@ -918,7 +921,7 @@ describe('Nobid Adapter', function () { adUnitCode: ADUNIT_300x250 }] } - const result = spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); expect(result[0].meta.advertiserDomains).to.equal(ADOMAINS); }); }); @@ -994,12 +997,13 @@ describe('Nobid Adapter', function () { site: 2, ublock: ULIMIT, bids: [ - {id: 1, + { + id: 1, bdrid: 101, divid: ADUNIT_300x250, dealid: DEAL_ID, creativeid: CREATIVE_ID_300x250, - size: {'w': 300, 'h': 250}, + size: { 'w': 300, 'h': 250 }, adm: ADMARKUP_300x250, price: '' + PRICE_300x250 } @@ -1026,7 +1030,7 @@ describe('Nobid Adapter', function () { 'auctionId': '1d1a030790a475', } ]; - spec.interpretResponse({ body: response }, {bidderRequest: bidderRequest}); + spec.interpretResponse({ body: response }, { bidderRequest: bidderRequest }); const request = spec.buildRequests(bidRequests, bidderRequest); expect(request).to.equal(undefined); }); @@ -1035,30 +1039,30 @@ describe('Nobid Adapter', function () { describe('getUserSyncs', function () { const GDPR_CONSENT_STRING = 'GDPR_CONSENT_STRING'; it('should get correct user sync when iframeEnabled', function () { - const pixel = spec.getUserSyncs({iframeEnabled: true}) + const pixel = spec.getUserSyncs({ iframeEnabled: true }) expect(pixel[0].type).to.equal('iframe'); expect(pixel[0].url).to.equal('https://public.servenobid.com/sync.html'); }); it('should get correct user sync when iframeEnabled and pixelEnabled', function () { - const pixel = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}) + const pixel = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }) expect(pixel[0].type).to.equal('iframe'); expect(pixel[0].url).to.equal('https://public.servenobid.com/sync.html'); }); it('should get correct user sync when iframeEnabled', function () { - const pixel = spec.getUserSyncs({iframeEnabled: true}, {}, {gdprApplies: true, consentString: GDPR_CONSENT_STRING}) + const pixel = spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: GDPR_CONSENT_STRING }) expect(pixel[0].type).to.equal('iframe'); expect(pixel[0].url).to.equal('https://public.servenobid.com/sync.html?gdpr=1&gdpr_consent=' + GDPR_CONSENT_STRING); }); it('should get correct user sync when !iframeEnabled', function () { - const pixel = spec.getUserSyncs({iframeEnabled: false}) + const pixel = spec.getUserSyncs({ iframeEnabled: false }) expect(pixel.length).to.equal(0); }); it('should get correct user sync when !iframeEnabled and pixelEnabled', function () { - const pixel = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{body: {syncs: ['sync_url']}}]) + const pixel = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { syncs: ['sync_url'] } }]) expect(pixel.length).to.equal(1); expect(pixel[0].type).to.equal('image'); expect(pixel[0].url).to.equal('sync_url'); diff --git a/test/spec/modules/nodalsAiRtdProvider_spec.js b/test/spec/modules/nodalsAiRtdProvider_spec.js index 9155e07b2ff..631cdfaca7b 100644 --- a/test/spec/modules/nodalsAiRtdProvider_spec.js +++ b/test/spec/modules/nodalsAiRtdProvider_spec.js @@ -197,7 +197,7 @@ describe('NodalsAI RTD Provider', () => { }); it('should return true when initialised with valid config and gdpr consent is null', function () { - const result = nodalsAiRtdSubmodule.init(validConfig, {gdpr: null}); + const result = nodalsAiRtdSubmodule.init(validConfig, { gdpr: null }); server.respond(); expect(result).to.be.true; @@ -494,7 +494,7 @@ describe('NodalsAI RTD Provider', () => { }); it('should return an empty object when getTargetingData throws error', () => { - createTargetingEngineStub({adUnit1: {someKey: 'someValue'}}, true); + createTargetingEngineStub({ adUnit1: { someKey: 'someValue' } }, true); setDataInLocalStorage({ data: successPubEndpointResponse, createdAt: Date.now(), @@ -669,7 +669,7 @@ describe('NodalsAI RTD Provider', () => { it('should not store function arguments in a queue when no data is in localstorage and make a HTTP request for data', () => { const callback = sinon.spy(); - const requestObj = {dummy: 'obj'} + const requestObj = { dummy: 'obj' } nodalsAiRtdSubmodule.getBidRequestData( requestObj, callback, validConfig, permissiveUserConsent ); @@ -686,7 +686,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const callback = sinon.spy(); - const reqBidsConfigObj = {dummy: 'obj'} + const reqBidsConfigObj = { dummy: 'obj' } nodalsAiRtdSubmodule.getBidRequestData( reqBidsConfigObj, callback, validConfig, permissiveUserConsent ); @@ -696,7 +696,7 @@ describe('NodalsAI RTD Provider', () => { expect(window.$nodals.cmdQueue).to.be.an('array').with.length(1); expect(window.$nodals.cmdQueue[0].cmd).to.equal('getBidRequestData'); expect(window.$nodals.cmdQueue[0].runtimeFacts).to.have.keys(['prebid.version', 'page.url']); - expect(window.$nodals.cmdQueue[0].data).to.deep.include({config: validConfig, reqBidsConfigObj, callback, userConsent: permissiveUserConsent}); + expect(window.$nodals.cmdQueue[0].data).to.deep.include({ config: validConfig, reqBidsConfigObj, callback, userConsent: permissiveUserConsent }); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('deps').that.deep.equals( successPubEndpointResponse.deps); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('facts').that.deep.includes( @@ -713,7 +713,7 @@ describe('NodalsAI RTD Provider', () => { }); const engine = createTargetingEngineStub(); const callback = sinon.spy(); - const reqBidsConfigObj = {dummy: 'obj'} + const reqBidsConfigObj = { dummy: 'obj' } nodalsAiRtdSubmodule.getBidRequestData( reqBidsConfigObj, callback, validConfig, permissiveUserConsent ); @@ -739,7 +739,7 @@ describe('NodalsAI RTD Provider', () => { }); const engine = createTargetingEngineStub(); const callback = sinon.spy(); - const reqBidsConfigObj = {dummy: 'obj'} + const reqBidsConfigObj = { dummy: 'obj' } const configWithManagedConsent = { params: { propertyId: '10312dd2', publisherProvidedConsent: true } }; nodalsAiRtdSubmodule.getBidRequestData( reqBidsConfigObj, callback, configWithManagedConsent, leastPermissiveUserConsent @@ -767,7 +767,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const engine = createTargetingEngineStub(); - const bidResponse = {dummy: 'obj', 'bid': 'foo'}; + const bidResponse = { dummy: 'obj', 'bid': 'foo' }; nodalsAiRtdSubmodule.onBidResponseEvent( bidResponse, validConfig, vendorRestrictiveUserConsent ); @@ -780,7 +780,7 @@ describe('NodalsAI RTD Provider', () => { }); it('should not store function arguments in a queue when no data is in localstorage and make a HTTP request for data', () => { - const bidResponse = {dummy: 'obj', 'bid': 'foo'}; + const bidResponse = { dummy: 'obj', 'bid': 'foo' }; nodalsAiRtdSubmodule.onBidResponseEvent( bidResponse, validConfig, permissiveUserConsent ); @@ -796,7 +796,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const userConsent = generateGdprConsent(); - const bidResponse = {dummy: 'obj', 'bid': 'foo'}; + const bidResponse = { dummy: 'obj', 'bid': 'foo' }; nodalsAiRtdSubmodule.onBidResponseEvent( bidResponse, validConfig, permissiveUserConsent ); @@ -805,7 +805,7 @@ describe('NodalsAI RTD Provider', () => { expect(window.$nodals.cmdQueue).to.be.an('array').with.length(1); expect(window.$nodals.cmdQueue[0].cmd).to.equal('onBidResponseEvent'); expect(window.$nodals.cmdQueue[0].runtimeFacts).to.have.keys(['prebid.version', 'page.url']); - expect(window.$nodals.cmdQueue[0].data).to.deep.include({config: validConfig, bidResponse, userConsent: permissiveUserConsent }); + expect(window.$nodals.cmdQueue[0].data).to.deep.include({ config: validConfig, bidResponse, userConsent: permissiveUserConsent }); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('deps').that.deep.equals( successPubEndpointResponse.deps); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('facts').that.deep.includes( @@ -821,7 +821,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const engine = createTargetingEngineStub(); - const bidResponse = {dummy: 'obj', 'bid': 'foo'}; + const bidResponse = { dummy: 'obj', 'bid': 'foo' }; nodalsAiRtdSubmodule.onBidResponseEvent( bidResponse, validConfig, permissiveUserConsent ); @@ -844,7 +844,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const engine = createTargetingEngineStub(); - const bidResponse = {dummy: 'obj', 'bid': 'foo'}; + const bidResponse = { dummy: 'obj', 'bid': 'foo' }; const configWithManagedConsent = { params: { propertyId: '10312dd2', publisherProvidedConsent: true } }; nodalsAiRtdSubmodule.onBidResponseEvent( bidResponse, configWithManagedConsent, leastPermissiveUserConsent @@ -870,7 +870,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const engine = createTargetingEngineStub(); - const auctionDetails = {dummy: 'obj', auction: 'foo'}; + const auctionDetails = { dummy: 'obj', auction: 'foo' }; nodalsAiRtdSubmodule.onAuctionEndEvent( auctionDetails, validConfig, vendorRestrictiveUserConsent ); @@ -883,7 +883,7 @@ describe('NodalsAI RTD Provider', () => { }); it('should not store function arguments in a queue when no data is in localstorage and make a HTTP request for data', () => { - const auctionDetails = {dummy: 'obj', auction: 'foo'}; + const auctionDetails = { dummy: 'obj', auction: 'foo' }; nodalsAiRtdSubmodule.onAuctionEndEvent( auctionDetails, validConfig, permissiveUserConsent ); @@ -898,7 +898,7 @@ describe('NodalsAI RTD Provider', () => { data: successPubEndpointResponse, createdAt: Date.now(), }); - const auctionDetails = {dummy: 'obj', auction: 'foo'}; + const auctionDetails = { dummy: 'obj', auction: 'foo' }; nodalsAiRtdSubmodule.onAuctionEndEvent( auctionDetails, validConfig, permissiveUserConsent ); @@ -907,7 +907,7 @@ describe('NodalsAI RTD Provider', () => { expect(window.$nodals.cmdQueue).to.be.an('array').with.length(1); expect(window.$nodals.cmdQueue[0].cmd).to.equal('onAuctionEndEvent'); expect(window.$nodals.cmdQueue[0].runtimeFacts).to.have.keys(['prebid.version', 'page.url']); - expect(window.$nodals.cmdQueue[0].data).to.deep.include({config: validConfig, auctionDetails, userConsent: permissiveUserConsent }); + expect(window.$nodals.cmdQueue[0].data).to.deep.include({ config: validConfig, auctionDetails, userConsent: permissiveUserConsent }); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('deps').that.deep.equals( successPubEndpointResponse.deps); expect(window.$nodals.cmdQueue[0].data.storedData).to.have.property('facts').that.deep.includes( @@ -924,7 +924,7 @@ describe('NodalsAI RTD Provider', () => { }); const engine = createTargetingEngineStub(); const userConsent = generateGdprConsent(); - const auctionDetails = {dummy: 'obj', auction: 'foo'}; + const auctionDetails = { dummy: 'obj', auction: 'foo' }; nodalsAiRtdSubmodule.onAuctionEndEvent( auctionDetails, validConfig, permissiveUserConsent ); @@ -947,7 +947,7 @@ describe('NodalsAI RTD Provider', () => { createdAt: Date.now(), }); const engine = createTargetingEngineStub(); - const auctionDetails = {dummy: 'obj', auction: 'foo'}; + const auctionDetails = { dummy: 'obj', auction: 'foo' }; const configWithManagedConsent = { params: { propertyId: '10312dd2', publisherProvidedConsent: true } }; nodalsAiRtdSubmodule.onAuctionEndEvent( auctionDetails, configWithManagedConsent, leastPermissiveUserConsent diff --git a/test/spec/modules/novatiqIdSystem_spec.js b/test/spec/modules/novatiqIdSystem_spec.js index b8906a9a1cc..1ea33ebd651 100644 --- a/test/spec/modules/novatiqIdSystem_spec.js +++ b/test/spec/modules/novatiqIdSystem_spec.js @@ -158,7 +158,7 @@ describe('novatiqIdSystem', function () { const novatiqId = {}; novatiqId.id = '81b001ec-8914-488c-a96e-8c220d4ee08895ef'; novatiqId.syncResponse = 2; - var config = {params: {removeAdditionalInfo: true}}; + var config = { params: { removeAdditionalInfo: true } }; const response = novatiqIdSubmodule.decode(novatiqId, config); expect(response.novatiq.ext.syncResponse).should.be.not.empty; expect(response.novatiq.snowflake.id).should.be.not.empty; diff --git a/test/spec/modules/oftmediaRtdProvider_spec.js b/test/spec/modules/oftmediaRtdProvider_spec.js index c8b43b14853..20746d9d955 100644 --- a/test/spec/modules/oftmediaRtdProvider_spec.js +++ b/test/spec/modules/oftmediaRtdProvider_spec.js @@ -17,7 +17,7 @@ const RTD_CONFIG = { bidderCode: 'appnexus', enrichRequest: true }, - }, ], + },], }; const TIMEOUT = 10; diff --git a/test/spec/modules/oguryBidAdapter_spec.js b/test/spec/modules/oguryBidAdapter_spec.js index 3cd7542f6c2..f6c09c5a829 100644 --- a/test/spec/modules/oguryBidAdapter_spec.js +++ b/test/spec/modules/oguryBidAdapter_spec.js @@ -3,7 +3,7 @@ import sinon from 'sinon'; import { spec, ortbConverterProps } from 'modules/oguryBidAdapter'; import * as utils from 'src/utils.js'; import { server } from '../../mocks/xhr.js'; -import {getDevicePixelRatio} from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; +import { getDevicePixelRatio } from '../../../libraries/devicePixelRatio/devicePixelRatio.js'; const BID_URL = 'https://mweb-hb.presage.io/api/header-bidding-request'; const TIMEOUT_URL = 'https://ms-ads-monitoring-events.presage.io/bid_timeout' @@ -114,8 +114,8 @@ describe('OguryBidAdapter', () => { bids: bidRequests, bidderRequestId: 'mock-uuid', auctionId: bidRequests[0].auctionId, - gdprConsent: {consentString: 'myConsentString', vendorData: {}, gdprApplies: true}, - gppConsent: {gppString: 'myGppString', gppData: {}, applicableSections: [7], parsedSections: {}}, + gdprConsent: { consentString: 'myConsentString', vendorData: {}, gdprApplies: true }, + gppConsent: { gppString: 'myGppString', gppData: {}, applicableSections: [7], parsedSections: {} }, timeout: 1000, ortb2 }; @@ -636,7 +636,7 @@ describe('OguryBidAdapter', () => { beforeEach(() => { windowTopStub = sinon.stub(utils, 'getWindowTop'); - windowTopStub.returns({ location: { href: currentLocation }, devicePixelRatio: stubbedDevicePixelRatio}); + windowTopStub.returns({ location: { href: currentLocation }, devicePixelRatio: stubbedDevicePixelRatio }); }); afterEach(() => { diff --git a/test/spec/modules/omnidexBidAdapter_spec.js b/test/spec/modules/omnidexBidAdapter_spec.js index 66bc66f047f..9a19f7e109b 100644 --- a/test/spec/modules/omnidexBidAdapter_spec.js +++ b/test/spec/modules/omnidexBidAdapter_spec.js @@ -1,14 +1,14 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, storage, } from 'modules/omnidexBidAdapter'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; import { hashCode, extractPID, @@ -19,7 +19,7 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -100,9 +100,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -119,7 +119,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -190,9 +190,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -205,7 +204,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -327,9 +326,9 @@ describe('OmnidexBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -400,9 +399,9 @@ describe('OmnidexBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -447,7 +446,7 @@ describe('OmnidexBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -456,7 +455,7 @@ describe('OmnidexBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.omni-dex.io/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -464,7 +463,7 @@ describe('OmnidexBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.omni-dex.io/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -476,7 +475,7 @@ describe('OmnidexBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.omni-dex.io/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -494,7 +493,7 @@ describe('OmnidexBidAdapter', function () { applicableSections: [7] } - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); expect(result).to.deep.equal([{ 'url': 'https://sync.omni-dex.io/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', @@ -510,12 +509,12 @@ describe('OmnidexBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -588,9 +587,9 @@ describe('OmnidexBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -611,7 +610,7 @@ describe('OmnidexBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -622,11 +621,11 @@ describe('OmnidexBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -641,7 +640,7 @@ describe('OmnidexBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -656,11 +655,11 @@ describe('OmnidexBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -673,18 +672,18 @@ describe('OmnidexBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -744,7 +743,7 @@ describe('OmnidexBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -760,8 +759,8 @@ describe('OmnidexBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/omsBidAdapter_spec.js b/test/spec/modules/omsBidAdapter_spec.js index f1f7df46843..bdbcc617588 100644 --- a/test/spec/modules/omsBidAdapter_spec.js +++ b/test/spec/modules/omsBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import * as utils from 'src/utils.js'; -import {spec} from 'modules/omsBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { spec } from 'modules/omsBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as winDimensions from 'src/utils/winDimensions.js'; const URL = 'https://rt.marphezis.com/hb'; @@ -34,7 +34,11 @@ describe('omsBidAdapter', function () { }; win = { document: { - visibilityState: 'visible' + visibilityState: 'visible', + documentElement: { + clientWidth: 800, + clientHeight: 600, + } }, location: { href: "http:/location" @@ -80,6 +84,7 @@ describe('omsBidAdapter', function () { sandbox = sinon.createSandbox(); sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); + sandbox.stub(winDimensions, 'getWinDimensions').returns(win); sandbox.stub(utils, 'getWindowTop').returns(win); sandbox.stub(utils, 'getWindowSelf').returns(win); }); @@ -135,7 +140,7 @@ describe('omsBidAdapter', function () { it('sets the proper banner object', function () { const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); }); it('sets the proper video object when ad unit media type is video', function () { @@ -187,7 +192,7 @@ describe('omsBidAdapter', function () { bidRequests[0].mediaTypes.banner.sizes = [300, 250]; const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }]); }); it('sends bidfloor param if present', function () { @@ -257,11 +262,21 @@ describe('omsBidAdapter', function () { }); it('sends coppa', function () { - const data = JSON.parse(spec.buildRequests(bidRequests, {ortb2: {regs: {coppa: 1}}}).data) + const data = JSON.parse(spec.buildRequests(bidRequests, { ortb2: { regs: { coppa: 1 } } }).data) expect(data.regs).to.not.be.undefined; expect(data.regs.coppa).to.equal(1); }); + it('sends instl property when ortb2Imp.instl = 1', function () { + const data = JSON.parse(spec.buildRequests([{ ...bidRequests[0], ortb2Imp: { instl: 1 } }]).data); + expect(data.imp[0].instl).to.equal(1); + }); + + it('ignores instl property when ortb2Imp.instl is falsy', function () { + const data = JSON.parse(spec.buildRequests(bidRequests).data); + expect(data.imp[0].instl).to.be.undefined; + }); + it('sends schain', function () { const data = JSON.parse(spec.buildRequests(bidRequests).data); expect(data).to.not.be.undefined; @@ -329,7 +344,7 @@ describe('omsBidAdapter', function () { context('when element is fully in view', function () { it('returns 100', function () { - Object.assign(element, {width: 600, height: 400}); + Object.assign(element, { width: 600, height: 400 }); const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); expect(payload.imp[0].banner.ext.viewability).to.equal(100); @@ -338,7 +353,7 @@ describe('omsBidAdapter', function () { context('when element is out of view', function () { it('returns 0', function () { - Object.assign(element, {x: -300, y: 0, width: 207, height: 320}); + Object.assign(element, { x: -300, y: 0, width: 207, height: 320 }); const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); expect(payload.imp[0].banner.ext.viewability).to.equal(0); @@ -347,9 +362,7 @@ describe('omsBidAdapter', function () { context('when element is partially in view', function () { it('returns percentage', function () { - const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions') - getWinDimensionsStub.returns({ innerHeight: win.innerHeight, innerWidth: win.innerWidth }); - Object.assign(element, {width: 800, height: 800}); + Object.assign(element, { width: 800, height: 800 }); const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); expect(payload.imp[0].banner.ext.viewability).to.equal(75); @@ -358,9 +371,7 @@ describe('omsBidAdapter', function () { context('when width or height of the element is zero', function () { it('try to use alternative values', function () { - const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions') - getWinDimensionsStub.returns({ innerHeight: win.innerHeight, innerWidth: win.innerWidth }); - Object.assign(element, {width: 0, height: 0}); + Object.assign(element, { width: 0, height: 0 }); bidRequests[0].mediaTypes.banner.sizes = [[800, 2400]]; const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); @@ -370,7 +381,7 @@ describe('omsBidAdapter', function () { context('when nested iframes', function () { it('returns \'na\'', function () { - Object.assign(element, {width: 600, height: 400}); + Object.assign(element, { width: 600, height: 400 }); utils.getWindowTop.restore(); utils.getWindowSelf.restore(); @@ -385,7 +396,7 @@ describe('omsBidAdapter', function () { context('when tab is inactive', function () { it('returns 0', function () { - Object.assign(element, {width: 600, height: 400}); + Object.assign(element, { width: 600, height: 400 }); utils.getWindowTop.restore(); win.document.visibilityState = 'hidden'; diff --git a/test/spec/modules/oneKeyRtdProvider_spec.js b/test/spec/modules/oneKeyRtdProvider_spec.js index 70023e35196..b43965db2f8 100644 --- a/test/spec/modules/oneKeyRtdProvider_spec.js +++ b/test/spec/modules/oneKeyRtdProvider_spec.js @@ -1,5 +1,5 @@ -import {oneKeyDataSubmodule} from 'modules/oneKeyRtdProvider.js'; -import {getAdUnits} from '../../fixtures/fixtures.js'; +import { oneKeyDataSubmodule } from 'modules/oneKeyRtdProvider.js'; +import { getAdUnits } from '../../fixtures/fixtures.js'; const defaultSeed = { version: '0.1', @@ -91,7 +91,7 @@ describe('oneKeyDataSubmodule', () => { rtdConfig: { params: { proxyHostName: 'host', - bidders: [ 'bidder42', 'bidder24' ] + bidders: ['bidder42', 'bidder24'] } }, expectedFragment: { diff --git a/test/spec/modules/onetagBidAdapter_spec.js b/test/spec/modules/onetagBidAdapter_spec.js index dd37a929b45..edfd6e8b754 100644 --- a/test/spec/modules/onetagBidAdapter_spec.js +++ b/test/spec/modules/onetagBidAdapter_spec.js @@ -26,7 +26,7 @@ const getFloor = function(params) { floorPrice = 5.0; break; } - return {currency: params.currency, floor: floorPrice}; + return { currency: params.currency, floor: floorPrice }; }; describe('onetag', function () { @@ -110,7 +110,7 @@ describe('onetag', function () { currency: 'EUR', schema: { delimiter: '|', - fields: [ 'mediaType', 'size' ] + fields: ['mediaType', 'size'] }, values: { 'native|*': 1.10 @@ -180,7 +180,7 @@ describe('onetag', function () { currency: 'EUR', schema: { delimiter: '|', - fields: [ 'mediaType', 'size' ] + fields: ['mediaType', 'size'] }, values: { 'native|*': 1.10 @@ -201,7 +201,7 @@ describe('onetag', function () { currency: 'EUR', schema: { delimiter: '|', - fields: [ 'mediaType', 'size' ] + fields: ['mediaType', 'size'] }, values: { 'banner|300x250': 0.10 @@ -224,7 +224,7 @@ describe('onetag', function () { currency: 'EUR', schema: { delimiter: '|', - fields: [ 'mediaType', 'size' ] + fields: ['mediaType', 'size'] }, values: { 'video|640x480': 0.10 @@ -246,7 +246,7 @@ describe('onetag', function () { currency: 'EUR', schema: { delimiter: '|', - fields: [ 'mediaType', 'size' ] + fields: ['mediaType', 'size'] }, values: { 'video|640x480': 0.10 @@ -694,7 +694,7 @@ describe('onetag', function () { cids: ['iris_c73g5jq96mwso4d8'] }, // the bare minimum are the IDs. These IDs are the ones from the new IAB Content Taxonomy v3 - segment: [ { id: '687' }, { id: '123' } ] + segment: [{ id: '687' }, { id: '123' }] }] }, ext: { @@ -875,8 +875,8 @@ describe('onetag', function () { }, 'adrender': 1 }; - const responseWithDsa = {...response}; - responseWithDsa.body.bids.forEach(bid => bid.dsa = {...dsaResponseObj}); + const responseWithDsa = { ...response }; + responseWithDsa.body.bids.forEach(bid => bid.dsa = { ...dsaResponseObj }); const serverResponse = spec.interpretResponse(responseWithDsa, request); serverResponse.forEach(bid => expect(bid.meta.dsa).to.deep.equals(dsaResponseObj)); }); diff --git a/test/spec/modules/onomagicBidAdapter_spec.js b/test/spec/modules/onomagicBidAdapter_spec.js index 6b4d44f49ed..2f44f7fb17b 100644 --- a/test/spec/modules/onomagicBidAdapter_spec.js +++ b/test/spec/modules/onomagicBidAdapter_spec.js @@ -34,9 +34,12 @@ describe('onomagicBidAdapter', function() { }; win = { document: { - visibilityState: 'visible' + visibilityState: 'visible', + documentElement: { + clientWidth: 800, + clientHeight: 600 + } }, - innerWidth: 800, innerHeight: 600 }; @@ -57,6 +60,7 @@ describe('onomagicBidAdapter', function() { }]; sandbox = sinon.createSandbox(); + sandbox.stub(winDimensions, 'getWinDimensions').returns(win); sandbox.stub(document, 'getElementById').withArgs('adunit-code').returns(element); sandbox.stub(utils, 'getWindowTop').returns(win); sandbox.stub(utils, 'getWindowSelf').returns(win); @@ -113,14 +117,14 @@ describe('onomagicBidAdapter', function() { it('sets the proper banner object', function() { const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); }); it('accepts a single array as a size', function() { bidRequests[0].mediaTypes.banner.sizes = [300, 250]; const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }]); }); it('sends bidfloor param if present', function () { @@ -162,8 +166,6 @@ describe('onomagicBidAdapter', function() { context('when element is partially in view', function() { it('returns percentage', function() { - const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions') - getWinDimensionsStub.returns({ innerHeight: win.innerHeight, innerWidth: win.innerWidth }); Object.assign(element, { width: 800, height: 800 }); const request = spec.buildRequests(bidRequests); const payload = JSON.parse(request.data); @@ -173,8 +175,6 @@ describe('onomagicBidAdapter', function() { context('when width or height of the element is zero', function() { it('try to use alternative values', function() { - const getWinDimensionsStub = sandbox.stub(winDimensions, 'getWinDimensions') - getWinDimensionsStub.returns({ innerHeight: win.innerHeight, innerWidth: win.innerWidth }); Object.assign(element, { width: 0, height: 0 }); bidRequests[0].mediaTypes.banner.sizes = [[800, 2400]]; const request = spec.buildRequests(bidRequests); @@ -287,7 +287,7 @@ describe('onomagicBidAdapter', function() { }); describe('getUserSyncs ', () => { - const syncOptions = {iframeEnabled: true, pixelEnabled: true}; + const syncOptions = { iframeEnabled: true, pixelEnabled: true }; it('should not return', () => { const returnStatement = spec.getUserSyncs(syncOptions, []); diff --git a/test/spec/modules/ooloAnalyticsAdapter_spec.js b/test/spec/modules/ooloAnalyticsAdapter_spec.js index 3a86f567f05..fe088b18bdc 100644 --- a/test/spec/modules/ooloAnalyticsAdapter_spec.js +++ b/test/spec/modules/ooloAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ import ooloAnalytics, { PAGEVIEW_ID } from 'modules/ooloAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; import { EVENTS } from 'src/constants.js' import * as events from 'src/events' import { config } from 'src/config'; diff --git a/test/spec/modules/opaMarketplaceBidAdapter_spec.js b/test/spec/modules/opaMarketplaceBidAdapter_spec.js index 4a7b4895aef..297f4c79fe1 100644 --- a/test/spec/modules/opaMarketplaceBidAdapter_spec.js +++ b/test/spec/modules/opaMarketplaceBidAdapter_spec.js @@ -1,14 +1,14 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, storage, } from 'modules/opaMarketplaceBidAdapter'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; import { hashCode, extractPID, @@ -19,7 +19,7 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -100,9 +100,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -119,7 +119,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -190,9 +190,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -205,7 +204,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -327,9 +326,9 @@ describe('OpaMarketplaceBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -400,9 +399,9 @@ describe('OpaMarketplaceBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -447,7 +446,7 @@ describe('OpaMarketplaceBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.have.length(1); const url = new URL(result[0].url); expect(result[0].type).to.equal('iframe') @@ -457,7 +456,7 @@ describe('OpaMarketplaceBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.have.length(1); const url = new URL(result[0].url); expect(result[0].type).to.equal('iframe') @@ -467,7 +466,7 @@ describe('OpaMarketplaceBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.have.length(1); const url = new URL(result[0].url); expect(result[0].type).to.equal('image') @@ -480,7 +479,7 @@ describe('OpaMarketplaceBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.have.length(1); const url = new URL(result[0].url); expect(result[0].type).to.equal('iframe') @@ -500,7 +499,7 @@ describe('OpaMarketplaceBidAdapter', function () { applicableSections: [7] } - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); const url = new URL(result[0].url); expect(result).to.deep.equal([{ 'url': 'https://sync.opamarketplace.com/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', @@ -520,12 +519,12 @@ describe('OpaMarketplaceBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -598,9 +597,9 @@ describe('OpaMarketplaceBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -621,7 +620,7 @@ describe('OpaMarketplaceBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -632,11 +631,11 @@ describe('OpaMarketplaceBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -651,7 +650,7 @@ describe('OpaMarketplaceBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -666,11 +665,11 @@ describe('OpaMarketplaceBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -683,18 +682,18 @@ describe('OpaMarketplaceBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -754,7 +753,7 @@ describe('OpaMarketplaceBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -770,8 +769,8 @@ describe('OpaMarketplaceBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/openPairIdSystem_spec.js b/test/spec/modules/openPairIdSystem_spec.js index e6fbd653749..07a0cbc82a9 100644 --- a/test/spec/modules/openPairIdSystem_spec.js +++ b/test/spec/modules/openPairIdSystem_spec.js @@ -10,7 +10,7 @@ import { setSubmoduleRegistry } from '../../../modules/userId/index.js'; -import {createEidsArray, getEids} from '../../../modules/userId/eids.js'; +import { createEidsArray, getEids } from '../../../modules/userId/eids.js'; describe('openPairId', function () { let sandbox; @@ -26,25 +26,26 @@ describe('openPairId', function () { it('should read publisher id from specified clean room if configured with storageKey', function() { const publisherIds = ['dGVzdC1wYWlyLWlkMQ==', 'test-pair-id2', 'test-pair-id3']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('habu_pairId_custom').returns(btoa(JSON.stringify({'envelope': publisherIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('habu_pairId_custom').returns(btoa(JSON.stringify({ 'envelope': publisherIds }))); const id = openPairIdSubmodule.getId({ params: { habu: { storageKey: 'habu_pairId_custom' } - }}) + } + }) - expect(id).to.be.deep.equal({id: publisherIds}); + expect(id).to.be.deep.equal({ id: publisherIds }); }); it('should read publisher id from liveramp with default storageKey and additional clean room with configured storageKey', function() { const getDataStub = sandbox.stub(storage, 'getDataFromLocalStorage'); const liveRampPublisherIds = ['lr-test-pair-id1', 'lr-test-pair-id2', 'lr-test-pair-id3']; - getDataStub.withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': liveRampPublisherIds}))); + getDataStub.withArgs('_lr_pairId').returns(btoa(JSON.stringify({ 'envelope': liveRampPublisherIds }))); const habuPublisherIds = ['habu-test-pair-id1', 'habu-test-pair-id2', 'habu-test-pair-id3']; - getDataStub.withArgs('habu_pairId_custom').returns(btoa(JSON.stringify({'envelope': habuPublisherIds}))); + getDataStub.withArgs('habu_pairId_custom').returns(btoa(JSON.stringify({ 'envelope': habuPublisherIds }))); const id = openPairIdSubmodule.getId({ params: { @@ -52,9 +53,10 @@ describe('openPairId', function () { storageKey: 'habu_pairId_custom' }, liveramp: {} - }}) + } + }) - expect(id).to.be.deep.equal({id: habuPublisherIds.concat(liveRampPublisherIds)}); + expect(id).to.be.deep.equal({ id: habuPublisherIds.concat(liveRampPublisherIds) }); }); it('should log an error if no ID is found when getId', function() { @@ -67,7 +69,7 @@ describe('openPairId', function () { sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('pairId').returns(btoa(JSON.stringify(publisherIds))); const id = openPairIdSubmodule.getId({ params: {} }); - expect(id).to.be.deep.equal({id: publisherIds}); + expect(id).to.be.deep.equal({ id: publisherIds }); }); it('should read publisher id from cookie if exists', function() { @@ -75,39 +77,42 @@ describe('openPairId', function () { sandbox.stub(storage, 'getCookie').withArgs('pairId').returns(btoa(JSON.stringify(publisherIds))); const id = openPairIdSubmodule.getId({ params: {} }); - expect(id).to.be.deep.equal({id: publisherIds}); + expect(id).to.be.deep.equal({ id: publisherIds }); }); it('should read publisher id from default liveramp envelope local storage key if configured', function() { const publisherIds = ['test-pair-id1', 'test-pair-id2', 'test-pair-id3']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': publisherIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({ 'envelope': publisherIds }))); const id = openPairIdSubmodule.getId({ params: { liveramp: {} - }}) - expect(id).to.be.deep.equal({id: publisherIds}) + } + }) + expect(id).to.be.deep.equal({ id: publisherIds }) }); it('should read publisher id from default liveramp envelope cookie entry if configured', function() { const publisherIds = ['test-pair-id4', 'test-pair-id5', 'test-pair-id6']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': publisherIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({ 'envelope': publisherIds }))); const id = openPairIdSubmodule.getId({ params: { liveramp: {} - }}) - expect(id).to.be.deep.equal({id: publisherIds}) + } + }) + expect(id).to.be.deep.equal({ id: publisherIds }) }); it('should read publisher id from specified liveramp envelope cookie entry if configured with storageKey', function() { const publisherIds = ['test-pair-id7', 'test-pair-id8', 'test-pair-id9']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('lr_pairId_custom').returns(btoa(JSON.stringify({'envelope': publisherIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('lr_pairId_custom').returns(btoa(JSON.stringify({ 'envelope': publisherIds }))); const id = openPairIdSubmodule.getId({ params: { liveramp: { storageKey: 'lr_pairId_custom' } - }}) - expect(id).to.be.deep.equal({id: publisherIds}) + } + }) + expect(id).to.be.deep.equal({ id: publisherIds }) }); it('should not get data from storage if local storage and cookies are disabled', function () { @@ -155,7 +160,7 @@ describe('openPairId', function () { const publisherIds = [value]; - const stored = btoa(JSON.stringify({'envelope': publisherIds})); + const stored = btoa(JSON.stringify({ 'envelope': publisherIds })); const read = JSON.parse(atob(stored)); diff --git a/test/spec/modules/openwebBidAdapter_spec.js b/test/spec/modules/openwebBidAdapter_spec.js index 197cdb85d11..71649ddfbcc 100644 --- a/test/spec/modules/openwebBidAdapter_spec.js +++ b/test/spec/modules/openwebBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/openwebBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; import * as utils from 'src/utils.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; const ENDPOINT = 'https://hb.openwebmp.com/hb-multi'; const TEST_ENDPOINT = 'https://hb.openwebmp.com/hb-multi-test'; @@ -106,7 +106,7 @@ describe('openwebAdapter', function () { 'mediaTypes': { 'banner': { 'sizes': [ - [ 300, 250 ] + [300, 250] ] }, 'video': { @@ -333,7 +333,7 @@ describe('openwebAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -346,7 +346,7 @@ describe('openwebAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -354,7 +354,7 @@ describe('openwebAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); @@ -362,7 +362,7 @@ describe('openwebAdapter', function () { }); it('should not send the gpp param if gppConsent is false in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: false}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: false }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gpp'); @@ -370,7 +370,7 @@ describe('openwebAdapter', function () { }); it('should send the gpp param if gppConsent is true in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: {gppString: 'test-consent-string', applicableSections: [7]}}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: { gppString: 'test-consent-string', applicableSections: [7] } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gpp', 'test-consent-string'); @@ -431,15 +431,15 @@ describe('openwebAdapter', function () { 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -453,20 +453,20 @@ describe('openwebAdapter', function () { 'sua': { 'platform': { 'brand': 'macOS', - 'version': [ '12', '4', '0' ] + 'version': ['12', '4', '0'] }, 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, diff --git a/test/spec/modules/openxBidAdapter_spec.js b/test/spec/modules/openxBidAdapter_spec.js index dfcdecdf586..19382760a2a 100644 --- a/test/spec/modules/openxBidAdapter_spec.js +++ b/test/spec/modules/openxBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec, REQUEST_URL, SYNC_URL, DEFAULT_PH} from 'modules/openxBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from 'src/mediaTypes.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec, REQUEST_URL, SYNC_URL, DEFAULT_PH } from 'modules/openxBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import * as dnt from 'libraries/dnt/index.js'; // load modules that register ORTB processors @@ -15,10 +15,10 @@ import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/paapi.js'; -import {deepClone} from 'src/utils.js'; -import {version} from 'package.json'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {hook} from '../../../src/hook.js'; +import { deepClone } from 'src/utils.js'; +import { version } from 'package.json'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { hook } from '../../../src/hook.js'; const DEFAULT_SYNC = SYNC_URL + '?ph=' + DEFAULT_PH; const BidRequestBuilder = function BidRequestBuilder(options) { @@ -93,7 +93,7 @@ describe('OpenxRtbAdapter', function () { bidder: 'openx', params: {}, adUnitCode: 'adunit-code', - mediaTypes: {banner: {}}, + mediaTypes: { banner: {} }, sizes: [[300, 250], [300, 600]], bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', @@ -102,13 +102,13 @@ describe('OpenxRtbAdapter', function () { }); it('should return false when there is no delivery domain', function () { - bannerBid.params = {'unit': '12345678'}; + bannerBid.params = { 'unit': '12345678' }; expect(spec.isBidRequestValid(bannerBid)).to.equal(false); }); describe('when there is a delivery domain', function () { beforeEach(function () { - bannerBid.params = {delDomain: 'test-delivery-domain'} + bannerBid.params = { delDomain: 'test-delivery-domain' } }); it('should return false when there is no ad unit id and size', function () { @@ -364,7 +364,7 @@ describe('OpenxRtbAdapter', function () { }; beforeEach(function () { - mockBidderRequest = {refererInfo: {}}; + mockBidderRequest = { refererInfo: {} }; bidRequestsWithMediaTypes = [{ bidder: 'openx', @@ -504,7 +504,7 @@ describe('OpenxRtbAdapter', function () { params: { unit: '12345678', delDomain: 'test-del-domain', - customParams: {'Test1': 'testval1+', 'test2': ['testval2/', 'testval3']} + customParams: { 'Test1': 'testval1+', 'test2': ['testval2/', 'testval3'] } } } ); @@ -586,7 +586,7 @@ describe('OpenxRtbAdapter', function () { describe('FPD', function() { let bidRequests; - const mockBidderRequest = {refererInfo: {}}; + const mockBidderRequest = { refererInfo: {} }; beforeEach(function () { bidRequests = [{ @@ -803,27 +803,28 @@ describe('OpenxRtbAdapter', function () { describe('with user agent client hints', function () { it('should add device.sua if available', function () { - const bidderRequestWithUserAgentClientHints = { refererInfo: {}, + const bidderRequestWithUserAgentClientHints = { + refererInfo: {}, ortb2: { device: { sua: { source: 2, platform: { brand: 'macOS', - version: [ '12', '4', '0' ] + version: ['12', '4', '0'] }, browsers: [ { brand: 'Chromium', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Google Chrome', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Not;A=Brand', - version: [ '99', '0', '0', '0' ] + version: ['99', '0', '0', '0'] }], mobile: 0, model: 'Pro', @@ -831,12 +832,13 @@ describe('OpenxRtbAdapter', function () { architecture: 'x86' } } - }}; + } + }; let request = spec.buildRequests(bidRequests, bidderRequestWithUserAgentClientHints); expect(request[0].data.device.sua).to.exist; expect(request[0].data.device.sua).to.deep.equal(bidderRequestWithUserAgentClientHints.ortb2.device.sua); - const bidderRequestWithoutUserAgentClientHints = {refererInfo: {}, ortb2: {}}; + const bidderRequestWithoutUserAgentClientHints = { refererInfo: {}, ortb2: {} }; request = spec.buildRequests(bidRequests, bidderRequestWithoutUserAgentClientHints); expect(request[0].data.device?.sua).to.not.exist; }); @@ -1041,7 +1043,7 @@ describe('OpenxRtbAdapter', function () { it('should send a coppa flag there is when there is coppa param settings in the bid params', async function () { const request = spec.buildRequests(bidRequestsWithMediaTypes, await addFPDToBidderRequest(mockBidderRequest)); - request.params = {coppa: true}; + request.params = { coppa: true }; expect(request[0].data.regs.coppa).to.equal(1); }); @@ -1135,17 +1137,19 @@ describe('OpenxRtbAdapter', function () { bidId: 'test-bid-id-1', bidderRequestId: 'test-bid-request-1', auctionId: 'test-auction-1', - ortb2: {source: { - schain: schainConfig, - ext: {schain: schainConfig} - }} + ortb2: { + source: { + schain: schainConfig, + ext: { schain: schainConfig } + } + } }]; // Add schain to mockBidderRequest as well mockBidderRequest.ortb2 = { source: { schain: schainConfig, - ext: {schain: schainConfig} + ext: { schain: schainConfig } } }; }); @@ -1216,7 +1220,7 @@ describe('OpenxRtbAdapter', function () { }]; // enrich bid request with userId key/value - mockBidderRequest.ortb2 = {user: {ext: {eids}}} + mockBidderRequest.ortb2 = { user: { ext: { eids } } } const request = spec.buildRequests(bidRequests, mockBidderRequest); expect(request[0].data.user.ext.eids).to.eql(eids); }); @@ -1321,10 +1325,10 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; - bidResponse = {nbr: 0}; // Unknown error - response = spec.interpretResponse({body: bidResponse}, bidRequest); + bidResponse = { nbr: 0 }; // Unknown error + response = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1352,10 +1356,10 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; - bidResponse = {ext: {}, id: 'test-bid-id'}; - response = spec.interpretResponse({body: bidResponse}, bidRequest); + bidResponse = { ext: {}, id: 'test-bid-id' }; + response = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1383,10 +1387,10 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = ''; // Unknown error - response = spec.interpretResponse({body: bidResponse}, bidRequest); + response = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1436,10 +1440,10 @@ describe('OpenxRtbAdapter', function () { context('when there is a response, the common response properties', function () { beforeEach(function () { bidRequestConfigs = deepClone(SAMPLE_BID_REQUESTS); - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = deepClone(SAMPLE_BID_RESPONSE); - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; }); it('should return a price', function () { @@ -1515,7 +1519,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1533,7 +1537,7 @@ describe('OpenxRtbAdapter', function () { cur: 'AUS' }; - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; }); it('should return the proper mediaType', function () { @@ -1561,7 +1565,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1580,14 +1584,14 @@ describe('OpenxRtbAdapter', function () { }); it('should return the proper mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(Object.keys(bidRequestConfigs[0].mediaTypes)[0]); }); it('should return the proper vastUrl', function () { const winUrl = 'https//my.win.url'; bidResponse.seatbid[0].bid[0].nurl = winUrl - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.vastUrl).to.equal(winUrl); }); @@ -1615,7 +1619,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1631,7 +1635,7 @@ describe('OpenxRtbAdapter', function () { }); it('should return video mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(VIDEO); }); }); @@ -1671,7 +1675,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id-2' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1687,7 +1691,7 @@ describe('OpenxRtbAdapter', function () { }); it('should return banner mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(BANNER); }); }); @@ -1724,7 +1728,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1740,21 +1744,21 @@ describe('OpenxRtbAdapter', function () { }); it('should return the proper mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(Object.keys(bidRequestConfigs[0].mediaTypes)[0]); }); it('should return parsed adm JSON in native.ortb response field', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.native.ortb).to.deep.equal({ ver: '1.2', assets: [{ id: 1, required: 1, - title: {text: 'OpenX (Title)'} + title: { text: 'OpenX (Title)' } }], - link: {url: 'https://www.openx.com/'}, + link: { url: 'https://www.openx.com/' }, eventtrackers: [{ event: 1, method: 1, @@ -1797,7 +1801,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1813,7 +1817,7 @@ describe('OpenxRtbAdapter', function () { }); it('should return banner mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(BANNER); }); }); @@ -1864,7 +1868,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id-2' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1880,7 +1884,7 @@ describe('OpenxRtbAdapter', function () { }); it('should return native mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest).bids[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest).bids[0]; expect(bid.mediaType).to.equal(NATIVE); }); }); @@ -1911,7 +1915,7 @@ describe('OpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1949,7 +1953,7 @@ describe('OpenxRtbAdapter', function () { } }; - response = spec.interpretResponse({body: bidResponse}, bidRequest); + response = spec.interpretResponse({ body: bidResponse }, bidRequest); }); afterEach(function () { @@ -1972,7 +1976,7 @@ describe('OpenxRtbAdapter', function () { tagid: '12345678', banner: { topframe: 0, - format: bidRequestConfigs[0].mediaTypes.banner.sizes.map(([w, h]) => ({w, h})) + format: bidRequestConfigs[0].mediaTypes.banner.sizes.map(([w, h]) => ({ w, h })) }, ext: { divid: 'adunit-code', @@ -1988,42 +1992,42 @@ describe('OpenxRtbAdapter', function () { describe('user sync', function () { it('should register the default image pixel if no pixels available', function () { const syncs = spec.getUserSyncs( - {pixelEnabled: true}, + { pixelEnabled: true }, [] ); - expect(syncs).to.deep.equal([{type: 'image', url: DEFAULT_SYNC}]); + expect(syncs).to.deep.equal([{ type: 'image', url: DEFAULT_SYNC }]); }); it('should register custom syncUrl when exists', function () { const syncs = spec.getUserSyncs( - {pixelEnabled: true}, - [{body: {ext: {delDomain: 'www.url.com'}}}] + { pixelEnabled: true }, + [{ body: { ext: { delDomain: 'www.url.com' } } }] ); - expect(syncs).to.deep.equal([{type: 'image', url: 'https://www.url.com/w/1.0/pd'}]); + expect(syncs).to.deep.equal([{ type: 'image', url: 'https://www.url.com/w/1.0/pd' }]); }); it('should register custom syncUrl when exists', function () { const syncs = spec.getUserSyncs( - {pixelEnabled: true}, - [{body: {ext: {platform: 'abc'}}}] + { pixelEnabled: true }, + [{ body: { ext: { platform: 'abc' } } }] ); - expect(syncs).to.deep.equal([{type: 'image', url: SYNC_URL + '?ph=abc'}]); + expect(syncs).to.deep.equal([{ type: 'image', url: SYNC_URL + '?ph=abc' }]); }); it('when iframe sync is allowed, it should register an iframe sync', function () { const syncs = spec.getUserSyncs( - {iframeEnabled: true}, + { iframeEnabled: true }, [] ); - expect(syncs).to.deep.equal([{type: 'iframe', url: DEFAULT_SYNC}]); + expect(syncs).to.deep.equal([{ type: 'iframe', url: DEFAULT_SYNC }]); }); it('should prioritize iframe over image for user sync', function () { const syncs = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + { iframeEnabled: true, pixelEnabled: true }, [] ); - expect(syncs).to.deep.equal([{type: 'iframe', url: DEFAULT_SYNC}]); + expect(syncs).to.deep.equal([{ type: 'iframe', url: DEFAULT_SYNC }]); }); describe('when gdpr applies', function () { @@ -2041,8 +2045,8 @@ describe('OpenxRtbAdapter', function () { }); it('when there is a response, it should have the gdpr query params', () => { - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], gdprConsent ); @@ -2052,8 +2056,8 @@ describe('OpenxRtbAdapter', function () { }); it('should not send signals if no consent object is available', function () { - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], ); expect(url).to.not.have.string('gdpr_consent='); @@ -2067,8 +2071,8 @@ describe('OpenxRtbAdapter', function () { gppString: 'gpp-pixel-consent', applicableSections: [6, 7] } - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, undefined, @@ -2088,8 +2092,8 @@ describe('OpenxRtbAdapter', function () { gppString: 'gpp-pixel-consent', applicableSections: [6, 7] } - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], gdprConsent, undefined, @@ -2106,8 +2110,8 @@ describe('OpenxRtbAdapter', function () { const gppConsent = { applicableSections: [6, 7] } - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, undefined, @@ -2122,8 +2126,8 @@ describe('OpenxRtbAdapter', function () { const gppConsent = { gppString: 'gpp-pixel-consent', } - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, undefined, @@ -2139,8 +2143,8 @@ describe('OpenxRtbAdapter', function () { gppString: 'gpp-pixel-consent', applicableSections: [] } - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, undefined, @@ -2152,8 +2156,8 @@ describe('OpenxRtbAdapter', function () { }); it('should not send GPP query params when GPP consent object not available', function () { - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, undefined, undefined ); expect(url).to.not.have.string('gpp='); @@ -2170,8 +2174,8 @@ describe('OpenxRtbAdapter', function () { uspPixelUrl = `${DEFAULT_SYNC}&us_privacy=${privacyString}` }); it('should send the us privacy string, ', () => { - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], undefined, usPrivacyConsent @@ -2180,8 +2184,8 @@ describe('OpenxRtbAdapter', function () { }); it('should not send signals if no consent string is available', function () { - const [{url}] = spec.getUserSyncs( - {iframeEnabled: true, pixelEnabled: true}, + const [{ url }] = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, [], ); expect(url).to.not.have.string('us_privacy='); diff --git a/test/spec/modules/operaadsBidAdapter_spec.js b/test/spec/modules/operaadsBidAdapter_spec.js index 0ff16d72293..4c875eedb0a 100644 --- a/test/spec/modules/operaadsBidAdapter_spec.js +++ b/test/spec/modules/operaadsBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/operaadsBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from 'src/mediaTypes.js'; +import { expect } from 'chai'; +import { spec } from 'modules/operaadsBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes.js'; describe('Opera Ads Bid Adapter', function () { describe('Test isBidRequestValid', function () { @@ -274,7 +274,7 @@ describe('Opera Ads Bid Adapter', function () { bidder: 'operaads', bidderRequestId: '15246a574e859f', mediaTypes: { - banner: {sizes: [[300, 250]]} + banner: { sizes: [[300, 250]] } }, params: { placementId: 's12345678', @@ -814,7 +814,7 @@ describe('Opera Ads Bid Adapter', function () { describe('Test onBidWon', function () { it('onBidWon should not throw', function () { - expect(spec.onBidWon({nurl: '#', originalCpm: '1.04', currency: 'USD'})).to.not.throw; + expect(spec.onBidWon({ nurl: '#', originalCpm: '1.04', currency: 'USD' })).to.not.throw; }); }); diff --git a/test/spec/modules/operaadsIdSystem_spec.js b/test/spec/modules/operaadsIdSystem_spec.js index b6acb942331..466a092ff52 100644 --- a/test/spec/modules/operaadsIdSystem_spec.js +++ b/test/spec/modules/operaadsIdSystem_spec.js @@ -1,8 +1,8 @@ import { operaIdSubmodule } from 'modules/operaadsIdSystem' import * as ajaxLib from 'src/ajax.js' -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; const TEST_ID = 'opera-test-id'; const operaIdRemoteResponse = { uid: TEST_ID }; diff --git a/test/spec/modules/opscoBidAdapter_spec.js b/test/spec/modules/opscoBidAdapter_spec.js index c0095edb0f1..49ac49c1826 100644 --- a/test/spec/modules/opscoBidAdapter_spec.js +++ b/test/spec/modules/opscoBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/opscoBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {addFPDToBidderRequest} from "../../helpers/fpd.js"; +import { expect } from 'chai'; +import { spec } from 'modules/opscoBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { addFPDToBidderRequest } from "../../helpers/fpd.js"; import 'modules/priceFloors.js'; describe('opscoBidAdapter', function () { @@ -32,36 +32,36 @@ describe('opscoBidAdapter', function () { }); it('should return false when placementId is missing', function () { - const invalidBid = {...validBid}; + const invalidBid = { ...validBid }; delete invalidBid.params.placementId; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); it('should return false when publisherId is missing', function () { - const invalidBid = {...validBid}; + const invalidBid = { ...validBid }; delete invalidBid.params.publisherId; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); it('should return false when mediaTypes.banner.sizes is missing', function () { - const invalidBid = {...validBid}; + const invalidBid = { ...validBid }; delete invalidBid.mediaTypes.banner.sizes; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); it('should return false when mediaTypes.banner is missing', function () { - const invalidBid = {...validBid}; + const invalidBid = { ...validBid }; delete invalidBid.mediaTypes.banner; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); it('should return false when bid params are missing', function () { - const invalidBid = {bidder: 'opsco'}; + const invalidBid = { bidder: 'opsco' }; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); it('should return false when bid params are empty', function () { - const invalidBid = {bidder: 'opsco', params: {}}; + const invalidBid = { bidder: 'opsco', params: {} }; expect(spec.isBidRequestValid(invalidBid)).to.be.false; }); }); @@ -127,25 +127,25 @@ describe('opscoBidAdapter', function () { it('should send CCPA in the payload if present', async function () { const request = spec.buildRequests([validBid], await addFPDToBidderRequest({ ...bidderRequest, - ...{uspConsent: '1YYY'} + ...{ uspConsent: '1YYY' } })); expect(request.data.regs.ext.us_privacy).to.equal('1YYY'); }); it('should send eids in the payload if present', async function () { - const eids = [{source: 'test', uids: [{id: '123', ext: {}}]}]; + const eids = [{ source: 'test', uids: [{ id: '123', ext: {} }] }]; const request = spec.buildRequests([validBid], await addFPDToBidderRequest({ ...bidderRequest, - ortb2: {user: {ext: {eids: eids}}} + ortb2: { user: { ext: { eids: eids } } } })); expect(request.data.user.ext.eids).to.deep.equal(eids); }); it('should send schain in the payload if present', function () { - const schain = {'ver': '1.0', 'complete': 1, 'nodes': [{'asi': 'exchange1.com', 'sid': '1234', 'hp': 1}]}; + const schain = { 'ver': '1.0', 'complete': 1, 'nodes': [{ 'asi': 'exchange1.com', 'sid': '1234', 'hp': 1 }] }; const request = spec.buildRequests([validBid], { ...bidderRequest, - ortb2: {source: {ext: {schain: schain}}} + ortb2: { source: { ext: { schain: schain } } } }); expect(request.data.source.ext.schain).to.deep.equal(schain); }); @@ -241,10 +241,10 @@ describe('opscoBidAdapter', function () { ext: { usersync: { sovrn: { - syncs: [{type: 'iframe', url: 'https://sovrn.com/iframe_sync'}] + syncs: [{ type: 'iframe', url: 'https://sovrn.com/iframe_sync' }] }, appnexus: { - syncs: [{type: 'image', url: 'https://appnexus.com/image_sync'}] + syncs: [{ type: 'image', url: 'https://appnexus.com/image_sync' }] } } } @@ -257,26 +257,26 @@ describe('opscoBidAdapter', function () { }); it('should return empty array if neither iframe nor pixel is enabled', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should return syncs only for iframe sync type', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [RESPONSE]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('iframe'); expect(opts[0].url).to.equal(RESPONSE.body.ext.usersync.sovrn.syncs[0].url); }); it('should return syncs only for pixel sync types', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [RESPONSE]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('image'); expect(opts[0].url).to.equal(RESPONSE.body.ext.usersync.appnexus.syncs[0].url); }); it('should return syncs when both iframe and pixel are enabled', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [RESPONSE]); expect(opts.length).to.equal(2); }); }); diff --git a/test/spec/modules/optableBidAdapter_spec.js b/test/spec/modules/optableBidAdapter_spec.js index b7cf2e3b44d..ef9daeca74e 100644 --- a/test/spec/modules/optableBidAdapter_spec.js +++ b/test/spec/modules/optableBidAdapter_spec.js @@ -48,22 +48,22 @@ describe('optableBidAdapter', function() { }); describe('buildPAAPIConfigs', () => { - function makeRequest({bidId, site = 'mockSite', ae = 1}) { + function makeRequest({ bidId, site = 'mockSite', ae = 1 }) { return { bidId, params: { site }, ortb2Imp: { - ext: {ae} + ext: { ae } } } } it('should generate auction configs for ae requests', () => { const configs = spec.buildPAAPIConfigs([ - makeRequest({bidId: 'bid1', ae: 1}), - makeRequest({bidId: 'bid2', ae: 0}), - makeRequest({bidId: 'bid3', ae: 1}), + makeRequest({ bidId: 'bid1', ae: 1 }), + makeRequest({ bidId: 'bid2', ae: 0 }), + makeRequest({ bidId: 'bid3', ae: 1 }), ]); expect(configs.map(cfg => cfg.bidId)).to.eql(['bid1', 'bid3']); configs.forEach(cfg => sinon.assert.match(cfg.config, { diff --git a/test/spec/modules/optableRtdProvider_spec.js b/test/spec/modules/optableRtdProvider_spec.js index 271d31d0185..b408c0b991f 100644 --- a/test/spec/modules/optableRtdProvider_spec.js +++ b/test/spec/modules/optableRtdProvider_spec.js @@ -25,29 +25,29 @@ describe('Optable RTD Submodule', function () { }); it('trims bundleUrl if it contains extra spaces', function () { - const config = {params: {bundleUrl: ' https://cdn.optable.co/bundle.js '}}; + const config = { params: { bundleUrl: ' https://cdn.optable.co/bundle.js ' } }; expect(parseConfig(config).bundleUrl).to.equal('https://cdn.optable.co/bundle.js'); }); it('returns null bundleUrl for invalid bundleUrl format', function () { - expect(parseConfig({params: {bundleUrl: 'invalidURL'}}).bundleUrl).to.be.null; - expect(parseConfig({params: {bundleUrl: 'www.invalid.com'}}).bundleUrl).to.be.null; + expect(parseConfig({ params: { bundleUrl: 'invalidURL' } }).bundleUrl).to.be.null; + expect(parseConfig({ params: { bundleUrl: 'www.invalid.com' } }).bundleUrl).to.be.null; }); it('returns null bundleUrl for non-HTTPS bundleUrl', function () { - expect(parseConfig({params: {bundleUrl: 'http://cdn.optable.co/bundle.js'}}).bundleUrl).to.be.null; - expect(parseConfig({params: {bundleUrl: '//cdn.optable.co/bundle.js'}}).bundleUrl).to.be.null; - expect(parseConfig({params: {bundleUrl: '/bundle.js'}}).bundleUrl).to.be.null; + expect(parseConfig({ params: { bundleUrl: 'http://cdn.optable.co/bundle.js' } }).bundleUrl).to.be.null; + expect(parseConfig({ params: { bundleUrl: '//cdn.optable.co/bundle.js' } }).bundleUrl).to.be.null; + expect(parseConfig({ params: { bundleUrl: '/bundle.js' } }).bundleUrl).to.be.null; }); it('defaults adserverTargeting to true if missing', function () { expect(parseConfig( - {params: {bundleUrl: 'https://cdn.optable.co/bundle.js'}} + { params: { bundleUrl: 'https://cdn.optable.co/bundle.js' } } ).adserverTargeting).to.be.true; }); it('returns null handleRtd if handleRtd is not a function', function () { - expect(parseConfig({params: {handleRtd: 'notAFunction'}}).handleRtd).to.be.null; + expect(parseConfig({ params: { handleRtd: 'notAFunction' } }).handleRtd).to.be.null; }); }); @@ -56,7 +56,7 @@ describe('Optable RTD Submodule', function () { beforeEach(() => { sandbox = sinon.createSandbox(); - reqBidsConfigObj = {ortb2Fragments: {global: {}}}; + reqBidsConfigObj = { ortb2Fragments: { global: {} } }; mergeFn = sinon.spy(); window.optable = { instance: { @@ -71,7 +71,7 @@ describe('Optable RTD Submodule', function () { }); it('merges valid targeting data into the global ORTB2 object', async function () { - const targetingData = {ortb2: {user: {ext: {optable: 'testData'}}}}; + const targetingData = { ortb2: { user: { ext: { optable: 'testData' } } } }; window.optable.instance.targetingFromCache.returns(targetingData); window.optable.instance.targeting.resolves(targetingData); @@ -95,7 +95,7 @@ describe('Optable RTD Submodule', function () { }); it('uses targeting data from cache if available', async function () { - const targetingData = {ortb2: {user: {ext: {optable: 'testData'}}}}; + const targetingData = { ortb2: { user: { ext: { optable: 'testData' } } } }; window.optable.instance.targetingFromCache.returns(targetingData); await defaultHandleRtd(reqBidsConfigObj, {}, mergeFn); @@ -103,7 +103,7 @@ describe('Optable RTD Submodule', function () { }); it('calls targeting function if no data is found in cache', async function () { - const targetingData = {ortb2: {user: {ext: {optable: 'testData'}}}}; + const targetingData = { ortb2: { user: { ext: { optable: 'testData' } } } }; window.optable.instance.targetingFromCache.returns(null); // Dispatch event with targeting data after a short delay @@ -125,7 +125,7 @@ describe('Optable RTD Submodule', function () { beforeEach(() => { sandbox = sinon.createSandbox(); mergeFn = sinon.spy(); - reqBidsConfigObj = {ortb2Fragments: {global: {}}}; + reqBidsConfigObj = { ortb2Fragments: { global: {} } }; }); afterEach(() => { @@ -150,11 +150,11 @@ describe('Optable RTD Submodule', function () { beforeEach(() => { sandbox = sinon.createSandbox(); - reqBidsConfigObj = {ortb2Fragments: {global: {}}}; + reqBidsConfigObj = { ortb2Fragments: { global: {} } }; callback = sinon.spy(); - moduleConfig = {params: {bundleUrl: 'https://cdn.optable.co/bundle.js'}}; + moduleConfig = { params: { bundleUrl: 'https://cdn.optable.co/bundle.js' } }; - sandbox.stub(window, 'optable').value({cmd: []}); + sandbox.stub(window, 'optable').value({ cmd: [] }); sandbox.stub(window.document, 'createElement'); sandbox.stub(window.document, 'head'); }); @@ -191,7 +191,7 @@ describe('Optable RTD Submodule', function () { // Dispatch the event after a short delay setTimeout(() => { const event = new CustomEvent('optable-targeting:change', { - detail: {ortb2: {user: {ext: {optable: 'testData'}}}} + detail: { ortb2: { user: { ext: { optable: 'testData' } } } } }); window.dispatchEvent(event); }, 10); @@ -237,7 +237,7 @@ describe('Optable RTD Submodule', function () { // Dispatch event after a short delay setTimeout(() => { const event = new CustomEvent('optable-targeting:change', { - detail: {ortb2: {user: {ext: {optable: 'testData'}}}} + detail: { ortb2: { user: { ext: { optable: 'testData' } } } } }); window.dispatchEvent(event); }, 10); @@ -269,7 +269,7 @@ describe('Optable RTD Submodule', function () { // Dispatch event after a short delay setTimeout(() => { const event = new CustomEvent('optable-targeting:change', { - detail: {ortb2: {user: {ext: {optable: 'testData'}}}} + detail: { ortb2: { user: { ext: { optable: 'testData' } } } } }); window.dispatchEvent(event); }, 10); @@ -289,8 +289,8 @@ describe('Optable RTD Submodule', function () { beforeEach(() => { sandbox = sinon.createSandbox(); - moduleConfig = {params: {adserverTargeting: true}}; - window.optable = {instance: {targetingKeyValuesFromCache: sandbox.stub().returns({key1: 'value1'})}}; + moduleConfig = { params: { adserverTargeting: true } }; + window.optable = { instance: { targetingKeyValuesFromCache: sandbox.stub().returns({ key1: 'value1' }) } }; }); afterEach(() => { @@ -299,7 +299,7 @@ describe('Optable RTD Submodule', function () { it('returns correct targeting data when Optable data is available', function () { const result = getTargetingData(['adUnit1'], moduleConfig, {}, {}); - expect(result).to.deep.equal({adUnit1: {key1: 'value1'}}); + expect(result).to.deep.equal({ adUnit1: { key1: 'value1' } }); }); it('returns empty object when no Optable data is found', function () { @@ -313,10 +313,10 @@ describe('Optable RTD Submodule', function () { }); it('returns empty object when provided keys contain no data', function () { - window.optable.instance.targetingKeyValuesFromCache.returns({key1: []}); + window.optable.instance.targetingKeyValuesFromCache.returns({ key1: [] }); expect(getTargetingData(['adUnit1'], moduleConfig, {}, {})).to.deep.equal({}); - window.optable.instance.targetingKeyValuesFromCache.returns({key1: [], key2: [], key3: []}); + window.optable.instance.targetingKeyValuesFromCache.returns({ key1: [], key2: [], key3: [] }); expect(getTargetingData(['adUnit1'], moduleConfig, {}, {})).to.deep.equal({}); }); }); diff --git a/test/spec/modules/optidigitalBidAdapter_spec.js b/test/spec/modules/optidigitalBidAdapter_spec.js index 3b4ef61e961..baf561cba16 100755 --- a/test/spec/modules/optidigitalBidAdapter_spec.js +++ b/test/spec/modules/optidigitalBidAdapter_spec.js @@ -63,20 +63,19 @@ describe('optidigitalAdapterTests', function () { 'adserver': { 'name': 'gam', 'adslot': '/19968336/header-bid-tag-0' - }, - 'pbadslot': '/19968336/header-bid-tag-0' + } }, 'gpid': '/19968336/header-bid-tag-0' } }, 'mediaTypes': { 'banner': { - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ] + 'sizes': [[300, 250], [300, 600]] } }, 'adUnitCode': 'div-gpt-ad-1460505748561-0', 'transactionId': '0cb56262-9637-474d-a572-86fa860fd8b7', - 'sizes': [ [ 300, 250 ], [ 300, 600 ] ], + 'sizes': [[300, 250], [300, 600]], 'bidId': '245d89f17f289f', 'bidderRequestId': '199d7ffafa1e91', 'auctionId': 'b66f01cd-3441-4403-99fa-d8062e795933', @@ -212,7 +211,8 @@ describe('optidigitalAdapterTests', function () { it('should send bid request to given endpoint', function() { const request = spec.buildRequests(validBidRequests, bidderRequest); - expect(request.url).to.equal(ENDPOINT); + const finalEndpoint = `${ENDPOINT}/s123`; + expect(request.url).to.equal(finalEndpoint); }); it('should be bidRequest data', function () { @@ -282,6 +282,49 @@ describe('optidigitalAdapterTests', function () { expect(payload.imp[0].adContainerHeight).to.exist; }); + it('should read container size from DOM when divId exists', function () { + const containerId = 'od-test-container'; + const el = document.createElement('div'); + el.id = containerId; + el.style.width = '321px'; + el.style.height = '111px'; + el.style.position = 'absolute'; + el.style.left = '0'; + el.style.top = '0'; + document.body.appendChild(el); + + const validBidRequestsWithDivId = [ + { + 'bidder': 'optidigital', + 'bidId': '51ef8751f9aead', + 'params': { + 'publisherId': 's123', + 'placementId': 'Billboard_Top', + 'divId': containerId + }, + 'adUnitCode': containerId, + 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', + 'mediaTypes': { + 'banner': { + 'sizes': [[300, 50], [300, 250], [300, 600]] + } + }, + 'sizes': [[320, 50], [300, 250], [300, 600]], + 'bidderRequestId': '418b37f85e772c', + 'auctionId': '18fd8b8b0bd757' + } + ]; + + const request = spec.buildRequests(validBidRequestsWithDivId, bidderRequest); + const payload = JSON.parse(request.data); + try { + expect(payload.imp[0].adContainerWidth).to.equal(el.offsetWidth); + expect(payload.imp[0].adContainerHeight).to.equal(el.offsetHeight); + } finally { + document.body.removeChild(el); + } + }); + it('should add pageTemplate to payload if pageTemplate exsists in parameter', function () { const validBidRequestsWithDivId = [ { @@ -325,7 +368,8 @@ describe('optidigitalAdapterTests', function () { 'domain': 'example.com', 'publisher': { 'domain': 'example.com' - } + }, + 'keywords': 'key1,key2' }, 'device': { 'w': 1507, @@ -386,6 +430,12 @@ describe('optidigitalAdapterTests', function () { expect(payload.bapp).to.deep.equal(validBidRequests[0].params.bapp); }); + it('should add keywords to payload when site keywords present', function() { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.site.keywords).to.deep.equal('key1,key2'); + }); + it('should send empty GDPR consent and required set to false', function() { const request = spec.buildRequests(validBidRequests, bidderRequest); const payload = JSON.parse(request.data); @@ -401,6 +451,7 @@ describe('optidigitalAdapterTests', function () { 'vendorData': { 'hasGlobalConsent': false }, + 'addtlConsent': '1~7.12.35.62.66.70.89.93.108', 'apiVersion': 1 } const request = spec.buildRequests(validBidRequests, bidderRequest); @@ -408,6 +459,7 @@ describe('optidigitalAdapterTests', function () { expect(payload.gdpr).to.exist; expect(payload.gdpr.consent).to.equal(consentString); expect(payload.gdpr.required).to.exist.and.to.be.true; + expect(payload.gdpr.addtlConsent).to.exist; }); it('should send empty GDPR consent to endpoint', function() { @@ -425,6 +477,22 @@ describe('optidigitalAdapterTests', function () { expect(payload.gdpr.consent).to.equal(''); }); + it('should send GDPR consent and required set to false when gdprApplies is not boolean', function() { + let consentString = 'DFR8KRePoQNsRREZCADBG+A=='; + bidderRequest.gdprConsent = { + 'consentString': consentString, + 'gdprApplies': "", + 'vendorData': { + 'hasGlobalConsent': false + }, + 'apiVersion': 1 + } + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.gdpr.consent).to.equal(consentString); + expect(payload.gdpr.required).to.exist.and.to.be.false; + }); + it('should send uspConsent to given endpoint', function() { bidderRequest.uspConsent = '1YYY'; const request = spec.buildRequests(validBidRequests, bidderRequest); @@ -457,6 +525,21 @@ describe('optidigitalAdapterTests', function () { expect(payload.gpp).to.exist; }); + it('should set testMode when optidigitalTestMode flag present in location', function() { + const originalUrl = window.location.href; + const newUrl = originalUrl.includes('optidigitalTestMode=true') + ? originalUrl + : `${window.location.pathname}${window.location.search}${window.location.search && window.location.search.length ? '&' : '?'}optidigitalTestMode=true${window.location.hash || ''}`; + try { + window.history.pushState({}, '', newUrl); + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.testMode).to.equal(true); + } finally { + window.history.replaceState({}, '', originalUrl); + } + }); + it('should use appropriate mediaTypes banner sizes', function() { const mediaTypesBannerSize = { 'mediaTypes': { @@ -532,6 +615,23 @@ describe('optidigitalAdapterTests', function () { expect(payload.user).to.deep.equal(undefined); }); + it('should add gpid to payload when gpid', function() { + validBidRequests[0].ortb2Imp = { + 'ext': { + 'data': { + 'adserver': { + 'name': 'gam', + 'adslot': '/19968336/header-bid-tag-0' + } + }, + 'gpid': '/19968336/header-bid-tag-0' + } + }; + const request = spec.buildRequests(validBidRequests, bidderRequest); + const payload = JSON.parse(request.data); + expect(payload.imp[0].gpid).to.deep.equal('/19968336/header-bid-tag-0'); + }); + function returnBannerSizes(mediaTypes, expectedSizes) { const bidRequest = Object.assign(validBidRequests[0], mediaTypes); const request = spec.buildRequests([bidRequest], bidderRequest); @@ -563,27 +663,27 @@ describe('optidigitalAdapterTests', function () { }); it('should return appropriate URL with GDPR equals to 1 and GDPR consent', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurlIframe}&gdpr=1&gdpr_consent=foo` }]); }); it('should return appropriate URL with GDPR equals to 0 and GDPR consent', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: false, consentString: 'foo'}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: false, consentString: 'foo' }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurlIframe}&gdpr=0&gdpr_consent=foo` }]); }); it('should return appropriate URL with GDPR equals to 1 and no consent', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: undefined}, undefined)).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: undefined }, undefined)).to.deep.equal([{ type: 'iframe', url: `${syncurlIframe}&gdpr=1&gdpr_consent=` }]); }); it('should return appropriate URL with GDPR equals to 1, GDPR consent and US Privacy consent', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, 'fooUsp')).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, 'fooUsp')).to.deep.equal([{ type: 'iframe', url: `${syncurlIframe}&gdpr=1&gdpr_consent=foo&us_privacy=fooUsp` }]); }); it('should return appropriate URL with GDPR equals to 1, GDPR consent, US Privacy consent and GPP consent', function() { - expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {gdprApplies: true, consentString: 'foo'}, 'fooUsp', {gppString: 'fooGpp', applicableSections: [7]})).to.deep.equal([{ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, 'fooUsp', { gppString: 'fooGpp', applicableSections: [7] })).to.deep.equal([{ type: 'iframe', url: `${syncurlIframe}&gdpr=1&gdpr_consent=foo&us_privacy=fooUsp&gpp=fooGpp&gpp_sid=7` }]); }); diff --git a/test/spec/modules/optimonAnalyticsAdapter_spec.js b/test/spec/modules/optimonAnalyticsAdapter_spec.js index 270f3aec395..e7f5ddf91a8 100644 --- a/test/spec/modules/optimonAnalyticsAdapter_spec.js +++ b/test/spec/modules/optimonAnalyticsAdapter_spec.js @@ -3,7 +3,7 @@ import { expect } from 'chai'; import optimonAnalyticsAdapter from '../../../modules/optimonAnalyticsAdapter.js'; import adapterManager from 'src/adapterManager'; import * as events from 'src/events'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expectEvents } from '../../helpers/analytics.js'; const AD_UNIT_CODE = 'demo-adunit-1'; const PUBLISHER_CONFIG = { diff --git a/test/spec/modules/optoutBidAdapter_spec.js b/test/spec/modules/optoutBidAdapter_spec.js index 0b8e9574ba1..e92e76fc39d 100644 --- a/test/spec/modules/optoutBidAdapter_spec.js +++ b/test/spec/modules/optoutBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { spec } from 'modules/optoutBidAdapter.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; describe('optoutAdapterTest', function () { describe('bidRequestValidity', function () { diff --git a/test/spec/modules/orakiBidAdapter_spec.js b/test/spec/modules/orakiBidAdapter_spec.js index 4a6b8fa7d36..f3f31be3e30 100644 --- a/test/spec/modules/orakiBidAdapter_spec.js +++ b/test/spec/modules/orakiBidAdapter_spec.js @@ -478,7 +478,7 @@ describe('OrakiBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -487,9 +487,7 @@ describe('OrakiBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.oraki.io/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -498,7 +496,7 @@ describe('OrakiBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.oraki.io/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/orbidderBidAdapter_spec.js b/test/spec/modules/orbidderBidAdapter_spec.js index dc33222f8ae..e949dcd9817 100644 --- a/test/spec/modules/orbidderBidAdapter_spec.js +++ b/test/spec/modules/orbidderBidAdapter_spec.js @@ -3,7 +3,7 @@ import { spec } from 'modules/orbidderBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import * as _ from 'lodash'; import { BANNER, NATIVE } from '../../../src/mediaTypes.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('orbidderBidAdapter', () => { const adapter = newBidder(spec); diff --git a/test/spec/modules/orbitsoftBidAdapter_spec.js b/test/spec/modules/orbitsoftBidAdapter_spec.js index 9615daa9887..001f175347c 100644 --- a/test/spec/modules/orbitsoftBidAdapter_spec.js +++ b/test/spec/modules/orbitsoftBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/orbitsoftBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/orbitsoftBidAdapter.js'; const ENDPOINT_URL = 'https://orbitsoft.com/php/ads/hb.phps'; const REFERRER_URL = 'http://referrer.url/?_='; @@ -65,7 +65,7 @@ describe('Orbitsoft adapter', function () { } } }, - refererInfo: {referer: REFERRER_URL}, + refererInfo: { referer: REFERRER_URL }, }; const isValid = spec.isBidRequestValid(validBid); expect(isValid).to.equal(true); @@ -105,7 +105,7 @@ describe('Orbitsoft adapter', function () { clickUrl: 'http://testclickurl.com' } }, - refererInfo: {referer: REFERRER_URL}, + refererInfo: { referer: REFERRER_URL }, }; const isValid = spec.isBidRequestValid(validBid); expect(isValid).to.equal(true); @@ -162,7 +162,7 @@ describe('Orbitsoft adapter', function () { } } ]; - const bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + const bids = spec.interpretResponse(serverResponse, { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(1); expect(bids[0].cpm).to.equal(serverResponse.body.cpm); expect(bids[0].width).to.equal(serverResponse.body.width); @@ -191,7 +191,7 @@ describe('Orbitsoft adapter', function () { cpm: 0 } }; - const bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + const bids = spec.interpretResponse(serverResponse, { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(0); }); @@ -214,7 +214,7 @@ describe('Orbitsoft adapter', function () { height: 0 } }; - const bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + const bids = spec.interpretResponse(serverResponse, { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(0); }); @@ -229,8 +229,8 @@ describe('Orbitsoft adapter', function () { } } ]; - const serverResponse = {error: 'error'}; - const bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + const serverResponse = { error: 'error' }; + const bids = spec.interpretResponse(serverResponse, { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(0); }); @@ -246,7 +246,7 @@ describe('Orbitsoft adapter', function () { } ]; const serverResponse = {}; - const bids = spec.interpretResponse(serverResponse, {'bidRequest': bidRequests[0]}); + const bids = spec.interpretResponse(serverResponse, { 'bidRequest': bidRequests[0] }); expect(bids).to.be.lengthOf(0); }); diff --git a/test/spec/modules/otmBidAdapter_spec.js b/test/spec/modules/otmBidAdapter_spec.js index 27da17b8415..3503247d221 100644 --- a/test/spec/modules/otmBidAdapter_spec.js +++ b/test/spec/modules/otmBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/otmBidAdapter'; +import { expect } from 'chai'; +import { spec } from 'modules/otmBidAdapter'; describe('otmBidAdapter', function () { it('pub_params', function () { @@ -42,7 +42,7 @@ describe('otmBidAdapter', function () { sizes: [[240, 400]] }]; - const bidderRequest = {refererInfo: {page: `https://github.com:3000/`, domain: 'github.com:3000'}} + const bidderRequest = { refererInfo: { page: `https://github.com:3000/`, domain: 'github.com:3000' } } const request = spec.buildRequests(bidRequestData, bidderRequest); const req_data = request[0].data; diff --git a/test/spec/modules/outbrainBidAdapter_spec.js b/test/spec/modules/outbrainBidAdapter_spec.js index 06b94d985f2..c3c33082403 100644 --- a/test/spec/modules/outbrainBidAdapter_spec.js +++ b/test/spec/modules/outbrainBidAdapter_spec.js @@ -647,7 +647,7 @@ describe('Outbrain Adapter', function () { const res = spec.buildRequests( [bidRequest], - {...commonBidderRequest, ...ortb2WithDeviceData}, + { ...commonBidderRequest, ...ortb2WithDeviceData }, ); expect(JSON.parse(res.data).device).to.deep.equal(ortb2WithDeviceData.ortb2.device); }); diff --git a/test/spec/modules/oxxionAnalyticsAdapter_spec.js b/test/spec/modules/oxxionAnalyticsAdapter_spec.js index da8c3f698b8..f569da9c181 100644 --- a/test/spec/modules/oxxionAnalyticsAdapter_spec.js +++ b/test/spec/modules/oxxionAnalyticsAdapter_spec.js @@ -1,4 +1,4 @@ -import oxxionAnalytics, {dereferenceWithoutRenderer} from 'modules/oxxionAnalyticsAdapter.js'; +import oxxionAnalytics, { dereferenceWithoutRenderer } from 'modules/oxxionAnalyticsAdapter.js'; import { expect } from 'chai'; import { server } from 'test/mocks/xhr.js'; @@ -324,7 +324,7 @@ describe('Oxxion Analytics', function () { }); it('test bidWon', function() { - window.OXXION_MODE = {'abtest': true}; + window.OXXION_MODE = { 'abtest': true }; adapterManager.registerAnalyticsAdapter({ code: 'oxxion', adapter: oxxionAnalytics diff --git a/test/spec/modules/oxxionRtdProvider_spec.js b/test/spec/modules/oxxionRtdProvider_spec.js index f5d2606e8ee..aedd0ffdea7 100644 --- a/test/spec/modules/oxxionRtdProvider_spec.js +++ b/test/spec/modules/oxxionRtdProvider_spec.js @@ -1,4 +1,4 @@ -import {oxxionSubmodule} from 'modules/oxxionRtdProvider.js'; +import { oxxionSubmodule } from 'modules/oxxionRtdProvider.js'; import 'src/prebid.js'; const utils = require('src/utils.js'); @@ -22,15 +22,15 @@ const request = { { 'code': 'msq_tag_200124_banner', 'mediaTypes': { 'banner': { 'sizes': [[300, 600]] } }, - 'bids': [{'bidder': 'appnexus', 'params': {'placementId': 123456}}], + 'bids': [{ 'bidder': 'appnexus', 'params': { 'placementId': 123456 } }], 'transactionId': 'de664ccb-e18b-4436-aeb0-362382eb1b40' }, { 'code': 'msq_tag_200125_video', 'mediaTypes': { 'video': { 'context': 'instream' }, playerSize: [640, 480], mimes: ['video/mp4'] }, 'bids': [ - {'bidder': 'mediasquare', 'params': {'code': 'publishername_atf_desktop_rg_video', 'owner': 'test'}}, - {'bidder': 'appnexusAst', 'params': {'placementId': 345678}}, + { 'bidder': 'mediasquare', 'params': { 'code': 'publishername_atf_desktop_rg_video', 'owner': 'test' } }, + { 'bidder': 'appnexusAst', 'params': { 'placementId': 345678 } }, ], 'transactionId': 'de664ccb-e18b-4436-aeb0-362382eb1b41' }, @@ -38,7 +38,7 @@ const request = { 'code': 'msq_tag_200125_banner', 'mediaTypes': { 'banner': { 'sizes': [[300, 250]] } }, 'bids': [ - {'bidder': 'appnexusAst', 'params': {'placementId': 345678}}, + { 'bidder': 'appnexusAst', 'params': { 'placementId': 345678 } }, ], 'transactionId': 'de664ccb-e18b-4436-aeb0-362382eb1b41' } @@ -114,10 +114,10 @@ const bids = [{ ]; const bidInterests = [ - {'id': 0, 'rate': 50.0, 'suggestion': true}, - {'id': 1, 'rate': 12.0, 'suggestion': false}, - {'id': 2, 'rate': 0.0, 'suggestion': true}, - {'id': 3, 'rate': 0.0, 'suggestion': false}, + { 'id': 0, 'rate': 50.0, 'suggestion': true }, + { 'id': 1, 'rate': 12.0, 'suggestion': false }, + { 'id': 2, 'rate': 0.0, 'suggestion': true }, + { 'id': 3, 'rate': 0.0, 'suggestion': false }, ]; const userConsent = { diff --git a/test/spec/modules/ozoneBidAdapter_spec.js b/test/spec/modules/ozoneBidAdapter_spec.js index 3eabc8a5190..6a04584280d 100644 --- a/test/spec/modules/ozoneBidAdapter_spec.js +++ b/test/spec/modules/ozoneBidAdapter_spec.js @@ -1,9 +1,9 @@ import { expect } from 'chai'; import { spec, getWidthAndHeightFromVideoObject, defaultSize } from 'modules/ozoneBidAdapter.js'; import { config } from 'src/config.js'; -import {Renderer} from '../../../src/Renderer.js'; +import { Renderer } from '../../../src/Renderer.js'; import * as utils from '../../../src/utils.js'; -import {deepSetValue, mergeDeep} from '../../../src/utils.js'; +import { deepSetValue, mergeDeep } from '../../../src/utils.js'; const OZONEURI = 'https://elb.the-ozone-project.com/openrtb2/auction'; const BIDDER_CODE = 'ozone'; spec.getGetParametersAsObject = function() { @@ -20,8 +20,8 @@ var validBidRequests = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } @@ -34,8 +34,8 @@ var validBidRequestsNoCustomData = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } @@ -49,8 +49,8 @@ var validBidRequestsMulti = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' }, @@ -62,8 +62,8 @@ var validBidRequestsMulti = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c0', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } @@ -769,8 +769,8 @@ var validBidRequestsWithUserIdData = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87', userId: { @@ -779,9 +779,9 @@ var validBidRequestsWithUserIdData = [ 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, 'criteoId': '1111criteoId', 'idl_env': 'liverampId', - 'lipb': {'lipbid': 'lipbidId123'}, - 'parrableId': {'eid': '01.5678.parrableid'}, - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} + 'lipb': { 'lipbid': 'lipbidId123' }, + 'parrableId': { 'eid': '01.5678.parrableid' }, + 'sharedid': { 'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22' } }, userIdAsEids: [ { @@ -827,14 +827,14 @@ var validBidRequestsWithUserIdData = [ { 'source': 'lipb', 'uids': [{ - 'id': {'lipbid': 'lipbidId123'}, + 'id': { 'lipbid': 'lipbidId123' }, 'atype': 1, }] }, { 'source': 'parrableId', 'uids': [{ - 'id': {'eid': '01.5678.parrableid'}, + 'id': { 'eid': '01.5678.parrableid' }, 'atype': 1, }] } @@ -849,7 +849,7 @@ var validBidRequestsMinimal = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + params: { publisherId: '9876abcd12-3', placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } @@ -862,8 +862,8 @@ var validBidRequestsNoSizes = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } ]; @@ -875,9 +875,9 @@ var validBidRequestsWithBannerMediaType = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } } ] }, - mediaTypes: {banner: {sizes: [[300, 250], [300, 600]]}}, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, banner: { format: [{ w: 300, h: 250 }, { w: 300, h: 600 }], h: 250, topframe: 1, w: 300 } }] }, + mediaTypes: { banner: { sizes: [[300, 250], [300, 600]] } }, transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } ]; @@ -889,9 +889,9 @@ var validBidRequestsWithNonBannerMediaTypesAndValidOutstreamVideo = [ bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, video: {skippable: true, playback_method: ['auto_play_sound_off'], targetDiv: 'some-different-div-id-to-my-adunitcode'} } ] }, - mediaTypes: {video: {mimes: ['video/mp4'], 'context': 'outstream', 'sizes': [640, 480], playerSize: [640, 480]}, native: {info: 'dummy data'}}, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ id: '2899ec066a91ff8', tagid: 'undefined', secure: 1, video: { skippable: true, playback_method: ['auto_play_sound_off'], targetDiv: 'some-different-div-id-to-my-adunitcode' } }] }, + mediaTypes: { video: { mimes: ['video/mp4'], 'context': 'outstream', 'sizes': [640, 480], playerSize: [640, 480] }, native: { info: 'dummy data' } }, transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' } ]; @@ -1091,8 +1091,8 @@ var validBidderRequest = { bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' }], @@ -1112,8 +1112,8 @@ var validBidderRequestWithCookieDeprecation = { bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' }], @@ -1172,8 +1172,8 @@ var bidderRequestWithFullGdpr = { bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, - params: { publisherId: '9876abcd12-3', customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [ { banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' } ] }, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, + params: { publisherId: '9876abcd12-3', customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' }] }, sizes: [[300, 250], [300, 600]], transactionId: '2e63c0ed-b10c-4008-aed5-84582cecfe87' }], @@ -1258,16 +1258,16 @@ var bidderRequestWithPartialGdpr = { bidRequestsCount: 1, bidder: 'ozone', bidderRequestId: '1c1586b27a1b5c8', - crumbs: {pubcid: '203a0692-f728-4856-87f6-9a25a6b63715'}, + crumbs: { pubcid: '203a0692-f728-4856-87f6-9a25a6b63715' }, params: { publisherId: '9876abcd12-3', - customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}], + customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }], placementId: '1310000099', siteId: '1234567890', id: 'fea37168-78f1-4a23-a40e-88437a99377e', auctionId: '27dcb421-95c6-4024-a624-3c03816c5f99', imp: [{ - banner: {topframe: 1, w: 300, h: 250, format: [{w: 300, h: 250}, {w: 300, h: 600}]}, + banner: { topframe: 1, w: 300, h: 250, format: [{ w: 300, h: 250 }, { w: 300, h: 600 }] }, id: '2899ec066a91ff8', secure: 1, tagid: 'undefined' @@ -1412,7 +1412,7 @@ var validResponse2Bids = { } } } - } ], + }], 'seat': 'appnexus' } ], @@ -1498,7 +1498,7 @@ var validResponse2BidsSameAdunit = { } } } - } ], + }], 'seat': 'ozappnexus' } ], @@ -2212,37 +2212,37 @@ describe('ozone Adapter', function () { it('should check deepSet means "unconditionally set element to this value, optionally building the path" and Object.assign will blend the keys together, neither will deeply merge nested objects successfully.', function () { let xx = {}; let yy = { - 'publisher': {'id': 123}, + 'publisher': { 'id': 123 }, 'page': 567, 'id': 900 }; deepSetValue(xx, 'site', yy); expect(xx.site).to.have.all.keys(['publisher', 'page', 'id']); - xx = {site: {'name': 'test1'}}; + xx = { site: { 'name': 'test1' } }; deepSetValue(xx, 'site', yy); - expect(xx.site).to.have.all.keys([ 'publisher', 'page', 'id']); - xx = {site: {'name': 'test1'}}; + expect(xx.site).to.have.all.keys(['publisher', 'page', 'id']); + xx = { site: { 'name': 'test1' } }; Object.assign(xx.site, yy); - expect(xx.site).to.have.all.keys([ 'publisher', 'page', 'id', 'name']); - xx = {site: {'name': 'test1'}}; + expect(xx.site).to.have.all.keys(['publisher', 'page', 'id', 'name']); + xx = { site: { 'name': 'test1' } }; deepSetValue(xx, 'site', yy); - expect(xx.site).to.have.all.keys([ 'publisher', 'page', 'id']); - xx = {regs: {dsa: {'val1:': 1}}}; - deepSetValue(xx, 'regs.ext.usprivacy', {'usp_key': 'usp_value'}); + expect(xx.site).to.have.all.keys(['publisher', 'page', 'id']); + xx = { regs: { dsa: { 'val1:': 1 } } }; + deepSetValue(xx, 'regs.ext.usprivacy', { 'usp_key': 'usp_value' }); expect(xx.regs).to.have.all.keys(['dsa', 'ext']); - xx = {regs: {dsa: {'val1:': 1}}}; - deepSetValue(xx.regs, 'ext.usprivacy', {'usp_key': 'usp_value'}); + xx = { regs: { dsa: { 'val1:': 1 } } }; + deepSetValue(xx.regs, 'ext.usprivacy', { 'usp_key': 'usp_value' }); expect(xx.regs).to.have.all.keys(['dsa', 'ext']); - let ozoneRequest = {user: { ext: {'data': 'some data ... '}, keywords: "a,b,c"}}; - Object.assign(ozoneRequest, {user: {ext: {eids: ['some eid', 'another one']}}}); + let ozoneRequest = { user: { ext: { 'data': 'some data ... ' }, keywords: "a,b,c" } }; + Object.assign(ozoneRequest, { user: { ext: { eids: ['some eid', 'another one'] } } }); expect(ozoneRequest.user.ext).to.have.all.keys(['eids']); }); it('should verify that mergeDeep does what I want it to do', function() { - let ozoneRequest = {user: { ext: {'data': 'some data ... '}, keywords: "a,b,c"}}; - ozoneRequest = mergeDeep(ozoneRequest, {user: {ext: {eids: ['some eid', 'another one']}}}); + let ozoneRequest = { user: { ext: { 'data': 'some data ... ' }, keywords: "a,b,c" } }; + ozoneRequest = mergeDeep(ozoneRequest, { user: { ext: { eids: ['some eid', 'another one'] } } }); expect(ozoneRequest.user.ext).to.have.all.keys(['eids', 'data']); - ozoneRequest = {user: { ext: {'data': 'some data ... '}, keywords: "a,b,c"}}; - mergeDeep(ozoneRequest, {user: {ext: {eids: ['some eid', 'another one']}}}); + ozoneRequest = { user: { ext: { 'data': 'some data ... ' }, keywords: "a,b,c" } }; + mergeDeep(ozoneRequest, { user: { ext: { eids: ['some eid', 'another one'] } } }); expect(ozoneRequest.user.ext).to.have.all.keys(['eids', 'data']); }); }); @@ -2264,7 +2264,7 @@ describe('ozone Adapter', function () { placementId: '1310000099', publisherId: '9876abcd12-3', siteId: '1234567890', - customData: [{'settings': {}, 'targeting': {'gender': 'bart', 'age': 'low'}}] + customData: [{ 'settings': {}, 'targeting': { 'gender': 'bart', 'age': 'low' } }] }, siteId: 1234567890 } @@ -2446,7 +2446,7 @@ describe('ozone Adapter', function () { 'placementId': '1234567890', 'publisherId': '9876abcd12-3', 'siteId': '1234567890', - 'customData': {'gender': 'bart', 'age': 'low'} + 'customData': { 'gender': 'bart', 'age': 'low' } } }; it('should not validate customData being an object, not an array', function () { @@ -2469,7 +2469,7 @@ describe('ozone Adapter', function () { params: { 'placementId': '1234567890', 'publisherId': '9876abcd12-3', - 'customData': [{'settings': {}, 'xx': {'gender': 'bart', 'age': 'low'}}], + 'customData': [{ 'settings': {}, 'xx': { 'gender': 'bart', 'age': 'low' } }], siteId: '1234567890' } }; @@ -2481,7 +2481,7 @@ describe('ozone Adapter', function () { params: { 'placementId': '1234567890', 'publisherId': '9876abcd12-3', - 'customData': [{'settings': {}, 'targeting': 'this should be an object'}], + 'customData': [{ 'settings': {}, 'targeting': 'this should be an object' }], siteId: '1234567890' } }; @@ -2508,8 +2508,7 @@ describe('ozone Adapter', function () { siteId: '1234567890' }, mediaTypes: { - video: { - mimes: ['video/mp4']} + video: { mimes: ['video/mp4'] } } }; it('should not validate video without context attribute', function () { @@ -2525,7 +2524,8 @@ describe('ozone Adapter', function () { mediaTypes: { video: { mimes: ['video/mp4'], - 'context': 'outstream'}, + 'context': 'outstream' + }, } }; it('should validate video outstream being sent', function () { @@ -2573,7 +2573,7 @@ describe('ozone Adapter', function () { }); it('ignores ozoneData in & after version 2.1.1', function () { const validBidRequestsWithOzoneData = JSON.parse(JSON.stringify(validBidRequests)); - validBidRequestsWithOzoneData[0].params.ozoneData = {'networkID': '3048', 'dfpSiteID': 'd.thesun', 'sectionID': 'homepage', 'path': '/', 'sec_id': 'null', 'sec': 'sec', 'topics': 'null', 'kw': 'null', 'aid': 'null', 'search': 'null', 'article_type': 'null', 'hide_ads': '', 'article_slug': 'null'}; + validBidRequestsWithOzoneData[0].params.ozoneData = { 'networkID': '3048', 'dfpSiteID': 'd.thesun', 'sectionID': 'homepage', 'path': '/', 'sec_id': 'null', 'sec': 'sec', 'topics': 'null', 'kw': 'null', 'aid': 'null', 'search': 'null', 'article_type': 'null', 'hide_ads': '', 'article_slug': 'null' }; const request = spec.buildRequests(validBidRequestsWithOzoneData, validBidderRequest); expect(request.data).to.be.a('string'); var data = JSON.parse(request.data); @@ -2603,11 +2603,11 @@ describe('ozone Adapter', function () { expect(request).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); }); it('should be able to handle non-single requests', function () { - config.setConfig({'ozone': {'singleRequest': false}}); + config.setConfig({ 'ozone': { 'singleRequest': false } }); const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); expect(request).to.be.a('array'); expect(request[0]).to.have.all.keys(['bidderRequest', 'data', 'method', 'url']); - config.setConfig({'ozone': {'singleRequest': true}}); + config.setConfig({ 'ozone': { 'singleRequest': true } }); }); it('should add gdpr consent information to the request when ozone is true', function () { const consentString = 'BOcocyaOcocyaAfEYDENCD-AAAAjx7_______9______9uz_Ov_v_f__33e8__9v_l_7_-___u_-33d4-_1vf99yfm1-7ftr3tp_87ues2_Xur__59__3z3_NphLgA=='; @@ -2618,8 +2618,8 @@ describe('ozone Adapter', function () { vendorData: { metadata: consentString, gdprApplies: true, - vendorConsents: {524: true}, - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} + vendorConsents: { 524: true }, + purposeConsents: { 1: true, 2: true, 3: true, 4: true, 5: true } } } const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); @@ -2653,7 +2653,7 @@ describe('ozone Adapter', function () { metadata: consentString, gdprApplies: true, vendorConsents: {}, - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} + purposeConsents: { 1: true, 2: true, 3: true, 4: true, 5: true } } }; const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); @@ -2664,7 +2664,7 @@ describe('ozone Adapter', function () { const gppString = 'gppConsentString'; const gppSections = [7, 8, 9]; const bidderRequest = JSON.parse(JSON.stringify(validBidderRequest)); - bidderRequest.ortb2 = {regs: {gpp: gppString, gpp_sid: gppSections}}; + bidderRequest.ortb2 = { regs: { gpp: gppString, gpp_sid: gppSections } }; const request = spec.buildRequests(validBidRequestsNoSizes, bidderRequest); const payload = JSON.parse(request.data); expect(payload.regs.ext.gpp).to.equal(gppString); @@ -2684,19 +2684,19 @@ describe('ozone Adapter', function () { vendorData: { metadata: consentString, gdprApplies: true, - vendorConsents: {524: true}, - purposeConsents: {1: true, 2: true, 3: true, 4: true, 5: true} + vendorConsents: { 524: true }, + purposeConsents: { 1: true, 2: true, 3: true, 4: true, 5: true } } }; const bidRequests = JSON.parse(JSON.stringify(validBidRequests)); bidRequests[0]['userId'] = { - 'digitrustid': {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, + 'digitrustid': { data: { id: 'DTID', keyv: 4, privacy: { optout: false }, producer: 'ABC', version: 2 } }, 'id5id': { uid: '1111', ext: { linkType: 2, abTestingControlGroup: false } }, 'idl_env': '3333', 'parrableid': 'eidVersion.encryptionKeyReference.encryptedValue', 'pubcid': '5555', 'tdid': '6666', - 'sharedid': {'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22'} + 'sharedid': { 'id': '01EAJWWNEPN3CYMM5N8M5VXY22', 'third': '01EAJWWNEPN3CYMM5N8M5VXY22' } }; bidRequests[0]['userIdAsEids'] = validBidRequestsWithUserIdData[0]['userIdAsEids']; const request = spec.buildRequests(bidRequests, bidderRequest); @@ -2733,32 +2733,32 @@ describe('ozone Adapter', function () { }); it('replaces the auction url for a config override', function () { const fakeOrigin = 'http://sometestendpoint'; - config.setConfig({'ozone': {'endpointOverride': {'origin': fakeOrigin}}}); + config.setConfig({ 'ozone': { 'endpointOverride': { 'origin': fakeOrigin } } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); expect(request.url).to.equal(fakeOrigin + '/openrtb2/auction'); expect(request.method).to.equal('POST'); const data = JSON.parse(request.data); expect(data.ext.ozone.origin).to.equal(fakeOrigin); - config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); + config.setConfig({ 'ozone': { 'kvpPrefix': null, 'endpointOverride': null } }); }); it('replaces the FULL auction url for a config override', function () { const fakeurl = 'http://sometestendpoint/myfullurl'; - config.setConfig({'ozone': {'endpointOverride': {'auctionUrl': fakeurl}}}); + config.setConfig({ 'ozone': { 'endpointOverride': { 'auctionUrl': fakeurl } } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); expect(request.url).to.equal(fakeurl); expect(request.method).to.equal('POST'); const data = JSON.parse(request.data); expect(data.ext.ozone.origin).to.equal(fakeurl); - config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); + config.setConfig({ 'ozone': { 'kvpPrefix': null, 'endpointOverride': null } }); }); it('replaces the renderer url for a config override', function () { const fakeUrl = 'http://renderer.com'; - config.setConfig({'ozone': {'endpointOverride': {'rendererUrl': fakeUrl}}}); + config.setConfig({ 'ozone': { 'endpointOverride': { 'rendererUrl': fakeUrl } } }); const result = spec.interpretResponse(getCleanValidVideoResponse(), validBidderRequest1OutstreamVideo2020); const bid = result[0]; expect(bid.renderer).to.be.an.instanceOf(Renderer); expect(bid.renderer.url).to.equal(fakeUrl); - config.setConfig({'ozone': {'kvpPrefix': null, 'endpointOverride': null}}); + config.setConfig({ 'ozone': { 'kvpPrefix': null, 'endpointOverride': null } }); }); it('should create a meta object on each bid returned', function () { const request = spec.buildRequests(validBidRequests, validBidderRequest); @@ -2769,7 +2769,7 @@ describe('ozone Adapter', function () { it('should use oztestmode GET value if set', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'oztestmode': 'mytestvalue_123'}; + return { 'oztestmode': 'mytestvalue_123' }; }; const request = specMock.buildRequests(validBidRequests, validBidderRequest); const data = JSON.parse(request.data); @@ -2779,7 +2779,7 @@ describe('ozone Adapter', function () { it('should ignore these GET params if present (removed 202410): ozf, ozpf, ozrp, ozip', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {ozf: '1', ozpf: '10', ozrp: '2', ozip: '123'}; + return { ozf: '1', ozpf: '10', ozrp: '2', ozip: '123' }; }; const request = specMock.buildRequests(validBidRequests, validBidderRequest); const data = JSON.parse(request.data); @@ -2788,7 +2788,7 @@ describe('ozone Adapter', function () { it('should use oztestmode GET value if set, even if there is no customdata in config', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'oztestmode': 'mytestvalue_123'}; + return { 'oztestmode': 'mytestvalue_123' }; }; const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest); const data = JSON.parse(request.data); @@ -2804,7 +2804,7 @@ describe('ozone Adapter', function () { expect(data.imp[0].ext.gpid).to.equal('/22037345/projectozone'); }); it('should batch into 10s if config is set to true', function () { - config.setConfig({ozone: {'batchRequests': true}}); + config.setConfig({ ozone: { 'batchRequests': true } }); var specMock = utils.deepClone(spec); const arrReq = []; for (let i = 0; i < 25; i++) { @@ -2817,7 +2817,7 @@ describe('ozone Adapter', function () { config.resetConfig(); }); it('should batch into 7 if config is set to 7', function () { - config.setConfig({ozone: {'batchRequests': 7}}); + config.setConfig({ ozone: { 'batchRequests': 7 } }); var specMock = utils.deepClone(spec); const arrReq = []; for (let i = 0; i < 25; i++) { @@ -2830,7 +2830,7 @@ describe('ozone Adapter', function () { config.resetConfig(); }); it('should not batch if config is set to false and singleRequest is true', function () { - config.setConfig({ozone: {'batchRequests': false, 'singleRequest': true}}); + config.setConfig({ ozone: { 'batchRequests': false, 'singleRequest': true } }); var specMock = utils.deepClone(spec); const arrReq = []; for (let i = 0; i < 15; i++) { @@ -2843,7 +2843,7 @@ describe('ozone Adapter', function () { config.resetConfig(); }); it('should not batch if config is set to invalid value -10 and singleRequest is true', function () { - config.setConfig({ozone: {'batchRequests': -10, 'singleRequest': true}}); + config.setConfig({ ozone: { 'batchRequests': -10, 'singleRequest': true } }); var specMock = utils.deepClone(spec); const arrReq = []; for (let i = 0; i < 15; i++) { @@ -2858,7 +2858,7 @@ describe('ozone Adapter', function () { it('should use GET values for batchRequests if found', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'batchRequests': '5'}; + return { 'batchRequests': '5' }; }; const arrReq = []; for (let i = 0; i < 25; i++) { @@ -2870,25 +2870,25 @@ describe('ozone Adapter', function () { expect(request.length).to.equal(5); specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'batchRequests': '10'}; + return { 'batchRequests': '10' }; }; request = specMock.buildRequests(arrReq, validBidderRequest); expect(request.length).to.equal(3); specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'batchRequests': true}; + return { 'batchRequests': true }; }; request = specMock.buildRequests(arrReq, validBidderRequest); expect(request.method).to.equal('POST'); specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'batchRequests': 'true'}; + return { 'batchRequests': 'true' }; }; request = specMock.buildRequests(arrReq, validBidderRequest); expect(request.method).to.equal('POST'); specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'batchRequests': -5}; + return { 'batchRequests': -5 }; }; request = specMock.buildRequests(arrReq, validBidderRequest); expect(request.method).to.equal('POST'); @@ -2896,7 +2896,7 @@ describe('ozone Adapter', function () { it('should use a valid ozstoredrequest GET value if set to override the placementId values, and set oz_rw if we find it', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'ozstoredrequest': '1122334455'}; + return { 'ozstoredrequest': '1122334455' }; }; const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest); const data = JSON.parse(request.data); @@ -2906,7 +2906,7 @@ describe('ozone Adapter', function () { it('should NOT use an invalid ozstoredrequest GET value if set to override the placementId values, and set oz_rw to 0', function() { var specMock = utils.deepClone(spec); specMock.getGetParametersAsObject = function() { - return {'ozstoredrequest': 'BADVAL'}; + return { 'ozstoredrequest': 'BADVAL' }; }; const request = specMock.buildRequests(validBidRequestsMinimal, validBidderRequest); const data = JSON.parse(request.data); @@ -2914,7 +2914,7 @@ describe('ozone Adapter', function () { expect(data.imp[0].ext.prebid.storedrequest.id).to.equal('1310000099'); }); it('should pick up the config value of coppa & set it in the request', function () { - config.setConfig({'coppa': true}); + config.setConfig({ 'coppa': true }); const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); const payload = JSON.parse(request.data); expect(payload.regs).to.include.keys('coppa'); @@ -2922,21 +2922,21 @@ describe('ozone Adapter', function () { config.resetConfig(); }); it('should pick up the config value of coppa & only set it in the request if its true', function () { - config.setConfig({'coppa': false}); + config.setConfig({ 'coppa': false }); const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); const payload = JSON.parse(request.data); expect(utils.deepAccess(payload, 'regs.coppa')).to.be.undefined; config.resetConfig(); }); it('should handle oz_omp_floor correctly', function () { - config.setConfig({'ozone': {'oz_omp_floor': 1.56}}); + config.setConfig({ 'ozone': { 'oz_omp_floor': 1.56 } }); const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); const payload = JSON.parse(request.data); expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.equal(1.56); config.resetConfig(); }); it('should ignore invalid oz_omp_floor values', function () { - config.setConfig({'ozone': {'oz_omp_floor': '1.56'}}); + config.setConfig({ 'ozone': { 'oz_omp_floor': '1.56' } }); const request = spec.buildRequests(validBidRequestsNoSizes, validBidderRequest); const payload = JSON.parse(request.data); expect(utils.deepAccess(payload, 'ext.ozone.oz_omp_floor')).to.be.undefined; @@ -2973,13 +2973,13 @@ describe('ozone Adapter', function () { expect(utils.deepAccess(payload2, 'ext.ozone.pv')).to.equal(utils.deepAccess(payload, 'ext.ozone.pv')); }); it('should indicate that the whitelist was used when it contains valid data', function () { - config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_ozappnexus_pb', 'oz_ozappnexus_imp_id']}}); + config.setConfig({ 'ozone': { 'oz_whitelist_adserver_keys': ['oz_ozappnexus_pb', 'oz_ozappnexus_imp_id'] } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const payload = JSON.parse(request.data); expect(payload.ext.ozone.oz_kvp_rw).to.equal(1); }); it('should indicate that the whitelist was not used when it contains no data', function () { - config.setConfig({'ozone': {'oz_whitelist_adserver_keys': []}}); + config.setConfig({ 'ozone': { 'oz_whitelist_adserver_keys': [] } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const payload = JSON.parse(request.data); expect(payload.ext.ozone.oz_kvp_rw).to.equal(0); @@ -3068,7 +3068,7 @@ describe('ozone Adapter', function () { for (let i = 0; i < keys.length; i++) { expect(allowed).to.include(keys[i]); } - expect(payload.imp[0].video.ext).to.include({'context': 'outstream'}); + expect(payload.imp[0].video.ext).to.include({ 'context': 'outstream' }); }); it('should handle standard floor config correctly', function () { config.setConfig({ @@ -3090,7 +3090,7 @@ describe('ozone Adapter', function () { } }); const localBidRequest = JSON.parse(JSON.stringify(validBidRequestsWithBannerMediaType)); - localBidRequest[0].getFloor = function(x) { return {'currency': 'USD', 'floor': 0.8} }; + localBidRequest[0].getFloor = function(x) { return { 'currency': 'USD', 'floor': 0.8 } }; const request = spec.buildRequests(localBidRequest, validBidderRequest); const payload = JSON.parse(request.data); expect(utils.deepAccess(payload, 'imp.0.floor.banner.currency')).to.equal('USD'); @@ -3165,7 +3165,7 @@ describe('ozone Adapter', function () { }); it('Single request: should use ortb auction ID & transaction ID values if set (this will be the case when publisher opts in with config)', function() { var specMock = utils.deepClone(spec); - config.setConfig({'ozone': {'singleRequest': true}}); + config.setConfig({ 'ozone': { 'singleRequest': true } }); const request = specMock.buildRequests(validBidRequestsWithAuctionIdTransactionId, validBidderRequest); expect(request).to.be.an('Object'); const payload = JSON.parse(request.data); @@ -3176,7 +3176,7 @@ describe('ozone Adapter', function () { }); it('non-Single request: should use ortb auction ID & transaction ID values if set (this will be the case when publisher opts in with config)', function() { var specMock = utils.deepClone(spec); - config.setConfig({'ozone': {'singleRequest': false}}); + config.setConfig({ 'ozone': { 'singleRequest': false } }); const request = specMock.buildRequests(validBidRequestsWithAuctionIdTransactionId, validBidderRequest); expect(request).to.be.an('Array'); const payload = JSON.parse(request[0].data); @@ -3187,7 +3187,7 @@ describe('ozone Adapter', function () { }); it('Batch request (flat array of single requests): should use ortb auction ID & transaction ID values if set (this will be the case when publisher opts in with config)', function() { var specMock = utils.deepClone(spec); - config.setConfig({'ozone': {'batchRequests': 3}}); + config.setConfig({ 'ozone': { 'batchRequests': 3 } }); const request = specMock.buildRequests(valid6BidRequestsWithAuctionIdTransactionId, validBidderRequest); expect(request).to.be.an('Array'); expect(request).to.have.lengthOf(2); @@ -3211,7 +3211,7 @@ describe('ozone Adapter', function () { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }, }; const request = spec.buildRequests(validBidRequests, bidderRequest); @@ -3238,7 +3238,7 @@ describe('ozone Adapter', function () { }); it('should build bid array with gdpr', function () { const validBR = JSON.parse(JSON.stringify(bidderRequestWithFullGdpr)); - validBR.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; + validBR.gdprConsent = { 'gdprApplies': 1, 'consentString': 'This is the gdpr consent string' }; const request = spec.buildRequests(validBidRequests, validBR); const result = spec.interpretResponse(validResponse, request); expect(result.length).to.equal(1); @@ -3253,7 +3253,7 @@ describe('ozone Adapter', function () { }); it('should build bid array with only partial gdpr', function () { var validBidderRequestWithGdpr = bidderRequestWithPartialGdpr.bidderRequest; - validBidderRequestWithGdpr.gdprConsent = {'gdprApplies': 1, 'consentString': 'This is the gdpr consent string'}; + validBidderRequestWithGdpr.gdprConsent = { 'gdprApplies': 1, 'consentString': 'This is the gdpr consent string' }; const request = spec.buildRequests(validBidRequests, validBidderRequestWithGdpr); const payload = JSON.parse(request.data); expect(payload.user.ext.consent).to.be.a('string'); @@ -3264,7 +3264,7 @@ describe('ozone Adapter', function () { expect(result).to.be.empty; }); it('should fail ok if seatbid is not an array', function () { - const result = spec.interpretResponse({'body': {'seatbid': 'nothing_here'}}, {}); + const result = spec.interpretResponse({ 'body': { 'seatbid': 'nothing_here' } }, {}); expect(result).to.be.an('array'); expect(result).to.be.empty; }); @@ -3293,13 +3293,13 @@ describe('ozone Adapter', function () { expect(result[0].ttl).to.equal(300); }); it('should handle oz_omp_floor_dollars correctly, inserting 1 as necessary', function () { - config.setConfig({'ozone': {'oz_omp_floor': 0.01}}); + config.setConfig({ 'ozone': { 'oz_omp_floor': 0.01 } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('1'); }); it('should handle oz_omp_floor_dollars correctly, inserting 0 as necessary', function () { - config.setConfig({'ozone': {'oz_omp_floor': 2.50}}); + config.setConfig({ 'ozone': { 'oz_omp_floor': 2.50 } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_omp')).to.equal('0'); @@ -3312,7 +3312,7 @@ describe('ozone Adapter', function () { it('should handle ext.bidder.ozone.floor correctly, setting flr & rid as necessary', function () { const request = spec.buildRequests(validBidRequests, validBidderRequest); const vres = JSON.parse(JSON.stringify(validResponse)); - vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 1, ruleId: 'ZjbsYE1q'}; + vres.body.seatbid[0].bid[0].ext.bidder.ozone = { floor: 1, ruleId: 'ZjbsYE1q' }; const result = spec.interpretResponse(vres, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(1); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbsYE1q'); @@ -3320,7 +3320,7 @@ describe('ozone Adapter', function () { it('should handle ext.bidder.ozone.floor correctly, inserting 0 as necessary', function () { const request = spec.buildRequests(validBidRequests, validBidderRequest); const vres = JSON.parse(JSON.stringify(validResponse)); - vres.body.seatbid[0].bid[0].ext.bidder.ozone = {floor: 0, ruleId: 'ZjbXXE1q'}; + vres.body.seatbid[0].bid[0].ext.bidder.ozone = { floor: 0, ruleId: 'ZjbXXE1q' }; const result = spec.interpretResponse(vres, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(0); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal('ZjbXXE1q'); @@ -3341,21 +3341,21 @@ describe('ozone Adapter', function () { expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid', null)).to.equal(null); }); it('should handle a valid whitelist, removing items not on the list & leaving others', function () { - config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_adId']}}); + config.setConfig({ 'ozone': { 'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_adId'] } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adId')).to.equal('2899ec066a91ff8-0-oz-0'); }); it('should ignore a whitelist if enhancedAdserverTargeting is false', function () { - config.setConfig({'ozone': {'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_imp_id'], 'enhancedAdserverTargeting': false}}); + config.setConfig({ 'ozone': { 'oz_whitelist_adserver_keys': ['oz_appnexus_crid', 'oz_appnexus_imp_id'], 'enhancedAdserverTargeting': false } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_imp_id')).to.be.undefined; }); it('should correctly handle enhancedAdserverTargeting being false', function () { - config.setConfig({'ozone': {'enhancedAdserverTargeting': false}}); + config.setConfig({ 'ozone': { 'enhancedAdserverTargeting': false } }); const request = spec.buildRequests(validBidRequests, validBidderRequest); const result = spec.interpretResponse(validResponse, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_adv')).to.be.undefined; @@ -3364,7 +3364,7 @@ describe('ozone Adapter', function () { it('should add flr into ads request if floor exists in the auction response', function () { const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest); const validres = JSON.parse(JSON.stringify(validResponse2Bids)); - validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'floor': 1}; + validres.body.seatbid[0].bid[0].ext.bidder.ozone = { 'floor': 1 }; const result = spec.interpretResponse(validres, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_flr')).to.equal(1); expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_flr', '')).to.equal(''); @@ -3372,7 +3372,7 @@ describe('ozone Adapter', function () { it('should add rid into ads request if ruleId exists in the auction response', function () { const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest); const validres = JSON.parse(JSON.stringify(validResponse2Bids)); - validres.body.seatbid[0].bid[0].ext.bidder.ozone = {'ruleId': 123}; + validres.body.seatbid[0].bid[0].ext.bidder.ozone = { 'ruleId': 123 }; const result = spec.interpretResponse(validres, request); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_appnexus_rid')).to.equal(123); expect(utils.deepAccess(result[1].adserverTargeting, 'oz_appnexus_rid', '')).to.equal(''); @@ -3427,13 +3427,15 @@ describe('ozone Adapter', function () { it('should handle fledge response', function () { const req = spec.buildRequests(validBidRequests, validBidderRequest); const objResp = JSON.parse(JSON.stringify(validResponse)); - objResp.body.ext = {igi: [{ - 'impid': '1', - 'igb': [{ - 'origin': 'https://paapi.dsp.com', - 'pbs': '{"key": "value"}' + objResp.body.ext = { + igi: [{ + 'impid': '1', + 'igb': [{ + 'origin': 'https://paapi.dsp.com', + 'pbs': '{"key": "value"}' + }] }] - }]}; + }; const result = spec.interpretResponse(objResp, req); expect(result).to.be.an('object'); expect(result.fledgeAuctionConfigs[0]['impid']).to.equal('1'); @@ -3464,11 +3466,11 @@ describe('ozone Adapter', function () { const validres = JSON.parse(JSON.stringify(validResponse2Bids)); validres.body.seatbid.push(JSON.parse(JSON.stringify(validres.body.seatbid[0]))); validres.body.seatbid[1].seat = 'marktest'; - validres.body.seatbid[1].bid[0].ext.bidder.prebid = {label: ['b1', 'b2', 'b3']}; + validres.body.seatbid[1].bid[0].ext.bidder.prebid = { label: ['b1', 'b2', 'b3'] }; validres.body.seatbid[1].bid[0].price = 10; validres.body.seatbid[1].bid[1].price = 0; - validres.body.seatbid[0].bid[0].ext.bidder.prebid = {label: ['bid1label1', 'bid1label2', 'bid1label3']}; - validres.body.seatbid[0].bid[1].ext.bidder.prebid = {label: ['bid2label']}; + validres.body.seatbid[0].bid[0].ext.bidder.prebid = { label: ['bid1label1', 'bid1label2', 'bid1label3'] }; + validres.body.seatbid[0].bid[1].ext.bidder.prebid = { label: ['bid2label'] }; const result = spec.interpretResponse(validres, request); expect(result.length).to.equal(4); expect(utils.deepAccess(result[0].adserverTargeting, 'oz_winner')).to.equal('marktest'); @@ -3481,7 +3483,7 @@ describe('ozone Adapter', function () { expect(utils.deepAccess(result[3].adserverTargeting, 'oz_labels')).to.equal('bid2label'); }); it('should not add labels in the adserver request if they are present in the auction response when config contains ozone.enhancedAdserverTargeting', function () { - config.setConfig({'ozone': {'enhancedAdserverTargeting': false}}); + config.setConfig({ 'ozone': { 'enhancedAdserverTargeting': false } }); const request = spec.buildRequests(validBidRequestsMulti, validBidderRequest); const validres = JSON.parse(JSON.stringify(validResponse2Bids)); validres.body.seatbid.push(JSON.parse(JSON.stringify(validres.body.seatbid[0]))); @@ -3515,7 +3517,7 @@ describe('ozone Adapter', function () { }); it('should append the various values if they exist', function() { spec.buildRequests(validBidRequests, validBidderRequest); - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1); + const result = spec.getUserSyncs({ iframeEnabled: true }, 'good server response', gdpr1); expect(result).to.be.an('array'); expect(result[0].url).to.include('publisherId=9876abcd12-3'); expect(result[0].url).to.include('siteId=1234567890'); @@ -3524,51 +3526,51 @@ describe('ozone Adapter', function () { }); it('should append ccpa (usp data)', function() { spec.buildRequests(validBidRequests, validBidderRequest); - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1, '1YYN'); + const result = spec.getUserSyncs({ iframeEnabled: true }, 'good server response', gdpr1, '1YYN'); expect(result).to.be.an('array'); expect(result[0].url).to.include('usp_consent=1YYN'); }); it('should use "" if no usp is sent to cookieSync', function() { spec.buildRequests(validBidRequests, validBidderRequest); - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1); + const result = spec.getUserSyncs({ iframeEnabled: true }, 'good server response', gdpr1); expect(result).to.be.an('array'); expect(result[0].url).to.include('usp_consent=&'); }); it('should add gpp if its present', function () { - const result = spec.getUserSyncs({iframeEnabled: true}, 'good server response', gdpr1, '1---', { gppString: 'gppStringHere', applicableSections: [7, 8, 9] }); + const result = spec.getUserSyncs({ iframeEnabled: true }, 'good server response', gdpr1, '1---', { gppString: 'gppStringHere', applicableSections: [7, 8, 9] }); expect(result[0].url).to.include('gpp=gppStringHere&gpp_sid=7,8,9'); }); }); describe('video object utils', function () { it('should find width & height from video object', function () { - const obj = {'playerSize': [640, 480], 'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'playerSize': [640, 480], 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result.w).to.equal(640); expect(result.h).to.equal(480); }); it('should find null from bad video object', function () { - const obj = {'playerSize': [], 'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'playerSize': [], 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result).to.be.null; }); it('should find null from bad video object2', function () { - const obj = {'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result).to.be.null; }); it('should find null from bad video object3', function () { - const obj = {'playerSize': 'should be an array', 'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'playerSize': 'should be an array', 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result).to.be.null; }); it('should find that player size is nested', function () { - const obj = {'playerSize': [[640, 480]], 'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'playerSize': [[640, 480]], 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result.w).to.equal(640); expect(result.h).to.equal(480); }); it('should fail if player size is 2 x nested', function () { - const obj = {'playerSize': [[[640, 480]]], 'mimes': ['video/mp4'], 'context': 'outstream'}; + const obj = { 'playerSize': [[[640, 480]]], 'mimes': ['video/mp4'], 'context': 'outstream' }; const result = getWidthAndHeightFromVideoObject(obj); expect(result).to.be.null; }); @@ -3594,12 +3596,12 @@ describe('ozone Adapter', function () { config.resetConfig() }) it('should return true if oz_request is false', function() { - config.setConfig({'ozone': {'oz_request': false}}); + config.setConfig({ 'ozone': { 'oz_request': false } }); const result = spec.blockTheRequest(); expect(result).to.be.true; }); it('should return false if oz_request is true', function() { - config.setConfig({'ozone': {'oz_request': true}}); + config.setConfig({ 'ozone': { 'oz_request': true } }); const result = spec.blockTheRequest(); expect(result).to.be.false; }); @@ -3676,7 +3678,7 @@ describe('ozone Adapter', function () { }); it('should correctly add video defaults if page config videoParams is defined, also check skip in the parent', function () { var specMock = utils.deepClone(spec); - config.setConfig({'ozone': {videoParams: {outstream: 3, instream: 1}}}); + config.setConfig({ 'ozone': { videoParams: { outstream: 3, instream: 1 } } }); const mediaTypes = { playerSize: [640, 480], mimes: ['video/mp4'], @@ -3712,19 +3714,19 @@ describe('ozone Adapter', function () { }); describe('setBidMediaTypeIfNotExist', function() { it('should leave the bid object alone if it already contains mediaType', function() { - const thisBid = {mediaType: 'marktest'}; + const thisBid = { mediaType: 'marktest' }; spec.setBidMediaTypeIfNotExist(thisBid, 'replacement'); expect(thisBid.mediaType).to.equal('marktest'); }); it('should change the bid object if it doesnt already contain mediaType', function() { - const thisBid = {someKey: 'someValue'}; + const thisBid = { someKey: 'someValue' }; spec.setBidMediaTypeIfNotExist(thisBid, 'replacement'); expect(thisBid.mediaType).to.equal('replacement'); }); }); describe('getLoggableBidObject', function() { it('should return an object without a "renderer" element', function () { - const obj = {'renderer': {}, 'somevalue': '', 'h': 100}; + const obj = { 'renderer': {}, 'somevalue': '', 'h': 100 }; const ret = spec.getLoggableBidObject(obj); expect(ret).to.not.have.own.property('renderer'); expect(ret.h).to.equal(100); @@ -3732,7 +3734,8 @@ describe('ozone Adapter', function () { }); describe('getUserIdFromEids', function() { it('should iterate over userIdAsEids when it is an object', function () { - let bid = { userIdAsEids: + let bid = { + userIdAsEids: [ { source: 'pubcid.org', @@ -3789,7 +3792,7 @@ describe('ozone Adapter', function () { expect(Object.keys(response).length).to.equal(0); }); it('find pubcid in the old location when there are eids and when there arent', function () { - let bid = {crumbs: {pubcid: 'some-random-id-value' }}; + let bid = { crumbs: { pubcid: 'some-random-id-value' } }; Object.defineProperty(bid, 'userIdAsEids', { value: undefined, writable: false, @@ -3909,14 +3912,14 @@ describe('ozone Adapter', function () { } } `); - const parsed = spec.pruneToExtPaths(jsonObj, {maxTestDepth: 2}); + const parsed = spec.pruneToExtPaths(jsonObj, { maxTestDepth: 2 }); expect(parsed).to.have.all.keys('site', 'user', 'regs', 'ext'); expect(Object.keys(parsed.site).length).to.equal(1); expect(parsed.site).to.have.all.keys('ext'); }); it('should prune a json object according to my params even when its empty', function () { const jsonObj = {}; - const parsed = spec.pruneToExtPaths(jsonObj, {maxTestDepth: 2}); + const parsed = spec.pruneToExtPaths(jsonObj, { maxTestDepth: 2 }); expect(Object.keys(parsed).length).to.equal(0); }); it('should prune a json object using Infinity as max depth', function () { @@ -4027,7 +4030,7 @@ describe('ozone Adapter', function () { } } `); - const parsed = spec.pruneToExtPaths(jsonObj, {maxTestDepth: Infinity}); + const parsed = spec.pruneToExtPaths(jsonObj, { maxTestDepth: Infinity }); expect(parsed.site.content.data[0].ext.segtax).to.equal('7'); }); it('should prune another json object', function () { @@ -4053,7 +4056,7 @@ describe('ozone Adapter', function () { } } }`); - const parsed = spec.pruneToExtPaths(jsonObj, {maxTestDepth: 2}); + const parsed = spec.pruneToExtPaths(jsonObj, { maxTestDepth: 2 }); expect(Object.keys(parsed.user).length).to.equal(1); expect(Object.keys(parsed)).to.have.members(['site', 'user']); expect(Object.keys(parsed.user)).to.have.members(['ext']); diff --git a/test/spec/modules/paapiForGpt_spec.js b/test/spec/modules/paapiForGpt_spec.js index eb75d51540d..de4517e1333 100644 --- a/test/spec/modules/paapiForGpt_spec.js +++ b/test/spec/modules/paapiForGpt_spec.js @@ -7,8 +7,8 @@ import { import * as gptUtils from '../../../libraries/gptUtils/gptUtils.js'; import 'modules/appnexusBidAdapter.js'; import 'modules/rubiconBidAdapter.js'; -import {deepSetValue} from '../../../src/utils.js'; -import {config} from 'src/config.js'; +import { deepSetValue } from '../../../src/utils.js'; +import { config } from 'src/config.js'; describe('paapiForGpt module', () => { let sandbox, fledgeAuctionConfig; @@ -68,14 +68,14 @@ describe('paapiForGpt module', () => { }); it('should reset only sellers with no fresh config', () => { - setGptConfig('au', gptSlots, [{seller: 's1'}, {seller: 's2'}]); + setGptConfig('au', gptSlots, [{ seller: 's1' }, { seller: 's2' }]); gptSlots.forEach(slot => slot.setConfig.resetHistory()); - setGptConfig('au', gptSlots, [{seller: 's1'}], true); + setGptConfig('au', gptSlots, [{ seller: 's1' }], true); gptSlots.forEach(slot => { sinon.assert.calledWith(slot.setConfig, { componentAuction: [{ configKey: 's1', - auctionConfig: {seller: 's1'} + auctionConfig: { seller: 's1' } }, { configKey: 's2', auctionConfig: null @@ -85,7 +85,7 @@ describe('paapiForGpt module', () => { }); it('should not reset sellers that were already reset', () => { - setGptConfig('au', gptSlots, [{seller: 's1'}]); + setGptConfig('au', gptSlots, [{ seller: 's1' }]); setGptConfig('au', gptSlots, [], true); gptSlots.forEach(slot => slot.setConfig.resetHistory()); setGptConfig('au', gptSlots, [], true); @@ -93,9 +93,9 @@ describe('paapiForGpt module', () => { }) it('should keep track of configuration history by ad unit', () => { - setGptConfig('au1', gptSlots, [{seller: 's1'}]); - setGptConfig('au1', gptSlots, [{seller: 's2'}], false); - setGptConfig('au2', gptSlots, [{seller: 's3'}]); + setGptConfig('au1', gptSlots, [{ seller: 's1' }]); + setGptConfig('au1', gptSlots, [{ seller: 's2' }], false); + setGptConfig('au2', gptSlots, [{ seller: 's3' }]); gptSlots.forEach(slot => slot.setConfig.resetHistory()); setGptConfig('au1', gptSlots, [], true); gptSlots.forEach(slot => { @@ -137,11 +137,11 @@ describe('paapiForGpt module', () => { }); it('should invoke once when adUnit is a string', () => { runHook('mock-au'); - expectFilters({adUnitCode: 'mock-au'}) + expectFilters({ adUnitCode: 'mock-au' }) }); it('should invoke once per ad unit when an array', () => { runHook(['au1', 'au2']); - expectFilters({adUnitCode: 'au1'}, {adUnitCode: 'au2'}); + expectFilters({ adUnitCode: 'au1' }, { adUnitCode: 'au2' }); }) }) describe('setPAAPIConfigForGpt', () => { @@ -166,7 +166,7 @@ describe('paapiForGpt module', () => { }); it('passes customSlotMatching to getSlots', () => { - getPAAPIConfig.returns({au1: {}}); + getPAAPIConfig.returns({ au1: {} }); setPAAPIConfigForGPT('mock-filters', 'mock-custom-matching'); sinon.assert.calledWith(getSlots, ['au1'], 'mock-custom-matching'); }) @@ -174,10 +174,10 @@ describe('paapiForGpt module', () => { it('sets GPT slot config for each ad unit that has PAAPI config, and resets the rest', () => { const cfg = { au1: { - componentAuctions: [{seller: 's1'}, {seller: 's2'}] + componentAuctions: [{ seller: 's1' }, { seller: 's2' }] }, au2: { - componentAuctions: [{seller: 's3'}] + componentAuctions: [{ seller: 's3' }] }, au3: null } diff --git a/test/spec/modules/paapi_spec.js b/test/spec/modules/paapi_spec.js index 2d491cdfe14..5cd76c59dc3 100644 --- a/test/spec/modules/paapi_spec.js +++ b/test/spec/modules/paapi_spec.js @@ -1,9 +1,9 @@ -import {expect} from 'chai'; -import {config} from '../../../src/config.js'; +import { expect } from 'chai'; +import { config } from '../../../src/config.js'; import adapterManager from '../../../src/adapterManager.js'; import * as utils from '../../../src/utils.js'; -import {deepAccess, deepClone} from '../../../src/utils.js'; -import {hook} from '../../../src/hook.js'; +import { deepAccess, deepClone } from '../../../src/utils.js'; +import { hook } from '../../../src/hook.js'; import 'modules/appnexusBidAdapter.js'; import 'modules/rubiconBidAdapter.js'; import { @@ -28,12 +28,12 @@ import { setResponsePaapiConfigs } from 'modules/paapi.js'; import * as events from 'src/events.js'; -import {EVENTS} from 'src/constants.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; -import {auctionManager} from '../../../src/auctionManager.js'; -import {stubAuctionIndex} from '../../helpers/indexStub.js'; -import {AuctionIndex} from '../../../src/auctionIndex.js'; -import {buildActivityParams} from '../../../src/activities/params.js'; +import { EVENTS } from 'src/constants.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { stubAuctionIndex } from '../../helpers/indexStub.js'; +import { AuctionIndex } from '../../../src/auctionIndex.js'; +import { buildActivityParams } from '../../../src/activities/params.js'; describe('paapi module', () => { let sandbox; @@ -58,7 +58,7 @@ describe('paapi module', () => { }); after(() => { - getPAAPISize.getHooks({hook: getPAAPISizeHook}).remove(); + getPAAPISize.getHooks({ hook: getPAAPISizeHook }).remove(); }); beforeEach(() => { @@ -69,7 +69,7 @@ describe('paapi module', () => { let bidderRequest, ajax; beforeEach(() => { ajax = sinon.stub(); - bidderRequest = {paapi: {}} + bidderRequest = { paapi: {} } }) function getWrappedAjax() { let wrappedAjax; @@ -86,16 +86,16 @@ describe('paapi module', () => { [ undefined, {}, - {adAuctionHeaders: true} + { adAuctionHeaders: true } ].forEach(options => it(`should set adAuctionHeaders = true (when options are ${JSON.stringify(options)})`, () => { getWrappedAjax()('url', {}, 'data', options); - sinon.assert.calledWith(ajax, 'url', {}, 'data', sinon.match({adAuctionHeaders: true})); + sinon.assert.calledWith(ajax, 'url', {}, 'data', sinon.match({ adAuctionHeaders: true })); })); it('should respect adAuctionHeaders: false', () => { - getWrappedAjax()('url', {}, 'data', {adAuctionHeaders: false}); - sinon.assert.calledWith(ajax, 'url', {}, 'data', sinon.match({adAuctionHeaders: false})); + getWrappedAjax()('url', {}, 'data', { adAuctionHeaders: false }); + sinon.assert.calledWith(ajax, 'url', {}, 'data', sinon.match({ adAuctionHeaders: false })); }) }); it('should not alter ajax when paapi is not enabled', () => { @@ -106,7 +106,7 @@ describe('paapi module', () => { describe('getPAAPIConfig', function () { let nextFnSpy, auctionConfig, paapiConfig; before(() => { - config.setConfig({paapi: {enabled: true}}); + config.setConfig({ paapi: { enabled: true } }); }); beforeEach(() => { auctionConfig = { @@ -122,11 +122,11 @@ describe('paapi module', () => { describe('on a single auction', function () { const auctionId = 'aid'; beforeEach(function () { - sandbox.stub(auctionManager, 'index').value(stubAuctionIndex({auctionId})); + sandbox.stub(auctionManager, 'index').value(stubAuctionIndex({ auctionId })); }); it('should call next()', function () { - const request = {auctionId, adUnitCode: 'auc'}; + const request = { auctionId, adUnitCode: 'auc' }; addPaapiConfigHook(nextFnSpy, request, paapiConfig); sinon.assert.calledWith(nextFnSpy, request, paapiConfig); }); @@ -154,14 +154,14 @@ describe('paapi module', () => { }); function addIgb(request, igb) { - addPaapiConfigHook(nextFnSpy, Object.assign({auctionId}, request), {igb}); + addPaapiConfigHook(nextFnSpy, Object.assign({ auctionId }, request), { igb }); } it('should be collected into an auction config', () => { - addIgb({adUnitCode: 'au1'}, igb1); - addIgb({adUnitCode: 'au1'}, igb2); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - const buyerConfig = getPAAPIConfig({auctionId}).au1.componentAuctions[0]; + addIgb({ adUnitCode: 'au1' }, igb1); + addIgb({ adUnitCode: 'au1' }, igb2); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: ['au1'] }); + const buyerConfig = getPAAPIConfig({ auctionId }).au1.componentAuctions[0]; sinon.assert.match(buyerConfig, { interestGroupBuyers: [igb1.origin, igb2.origin], ...buyerAuctionConfig @@ -171,14 +171,14 @@ describe('paapi module', () => { describe('FPD', () => { let ortb2, ortb2Imp; beforeEach(() => { - ortb2 = {'fpd': 1}; - ortb2Imp = {'fpd': 2}; + ortb2 = { 'fpd': 1 }; + ortb2Imp = { 'fpd': 2 }; }); function getBuyerAuctionConfig() { - addIgb({adUnitCode: 'au1', ortb2, ortb2Imp}, igb1); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1']}); - return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; + addIgb({ adUnitCode: 'au1', ortb2, ortb2Imp }, igb1); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: ['au1'] }); + return getPAAPIConfig({ auctionId }).au1.componentAuctions[0]; } it('should be added to auction config', () => { @@ -209,15 +209,15 @@ describe('paapi module', () => { describe('should collect auction configs', () => { let cf1, cf2; beforeEach(() => { - cf1 = {...auctionConfig, id: 1, seller: 'b1'}; - cf2 = {...auctionConfig, id: 2, seller: 'b2'}; - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, {config: cf1}); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, {config: cf2}); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); + cf1 = { ...auctionConfig, id: 1, seller: 'b1' }; + cf2 = { ...auctionConfig, id: 2, seller: 'b2' }; + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au1' }, { config: cf1 }); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au2' }, { config: cf2 }); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: ['au1', 'au2', 'au3'] }); }); it('and make them available at end of auction', () => { - sinon.assert.match(getPAAPIConfig({auctionId}), { + sinon.assert.match(getPAAPIConfig({ auctionId }), { au1: { componentAuctions: [cf1] }, @@ -228,7 +228,7 @@ describe('paapi module', () => { }); it('and filter them by ad unit', () => { - const cfg = getPAAPIConfig({auctionId, adUnitCode: 'au1'}); + const cfg = getPAAPIConfig({ auctionId, adUnitCode: 'au1' }); expect(Object.keys(cfg)).to.have.members(['au1']); sinon.assert.match(cfg.au1, { componentAuctions: [cf1] @@ -248,58 +248,58 @@ describe('paapi module', () => { expect(cfg.au3).to.eql(null); }); it('includes the targeted adUnit', () => { - expect(getPAAPIConfig({adUnitCode: 'au3'}, true)).to.eql({ + expect(getPAAPIConfig({ adUnitCode: 'au3' }, true)).to.eql({ au3: null }); }); it('includes the targeted auction', () => { - const cfg = getPAAPIConfig({auctionId}, true); + const cfg = getPAAPIConfig({ auctionId }, true); expect(Object.keys(cfg)).to.have.members(['au1', 'au2', 'au3']); expect(cfg.au3).to.eql(null); }); it('does not include non-existing ad units', () => { - expect(getPAAPIConfig({adUnitCode: 'other'})).to.eql({}); + expect(getPAAPIConfig({ adUnitCode: 'other' })).to.eql({}); }); it('does not include non-existing auctions', () => { - expect(getPAAPIConfig({auctionId: 'other'})).to.eql({}); + expect(getPAAPIConfig({ auctionId: 'other' })).to.eql({}); }); }); }); it('should drop auction configs after end of auction', () => { - events.emit(EVENTS.AUCTION_END, {auctionId}); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); - expect(getPAAPIConfig({auctionId})).to.eql({}); + events.emit(EVENTS.AUCTION_END, { auctionId }); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au' }, paapiConfig); + expect(getPAAPIConfig({ auctionId })).to.eql({}); }); describe('FPD', () => { let ortb2, ortb2Imp; beforeEach(() => { - ortb2 = {fpd: 1}; - ortb2Imp = {fpd: 2}; + ortb2 = { fpd: 1 }; + ortb2Imp = { fpd: 2 }; }); function getComponentAuctionConfig() { addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au1', - ortb2: {fpd: 1}, - ortb2Imp: {fpd: 2} + ortb2: { fpd: 1 }, + ortb2Imp: { fpd: 2 } }, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId}); - return getPAAPIConfig({auctionId}).au1.componentAuctions[0]; + events.emit(EVENTS.AUCTION_END, { auctionId }); + return getPAAPIConfig({ auctionId }).au1.componentAuctions[0]; } it('should be added to auctionSignals', () => { sinon.assert.match(getComponentAuctionConfig().auctionSignals, { - prebid: {ortb2, ortb2Imp} + prebid: { ortb2, ortb2Imp } }); }); it('should not override existing auctionSignals', () => { - auctionConfig.auctionSignals = {prebid: {ortb2: {fpd: 'original'}}}; + auctionConfig.auctionSignals = { prebid: { ortb2: { fpd: 'original' } } }; sinon.assert.match(getComponentAuctionConfig().auctionSignals, { prebid: { - ortb2: {fpd: 'original'}, + ortb2: { fpd: 'original' }, ortb2Imp } }); @@ -309,8 +309,8 @@ describe('paapi module', () => { auctionConfig.interestGroupBuyers = ['buyer.1', 'buyer.2']; const pbs = getComponentAuctionConfig().perBuyerSignals; sinon.assert.match(pbs, { - 'buyer.1': {prebid: {ortb2, ortb2Imp}}, - 'buyer.2': {prebid: {ortb2, ortb2Imp}} + 'buyer.1': { prebid: { ortb2, ortb2Imp } }, + 'buyer.2': { prebid: { ortb2, ortb2Imp } } }); }); @@ -343,17 +343,17 @@ describe('paapi module', () => { describe('onAuctionConfig', () => { const auctionId = 'aid'; it('is invoked with null configs when there\'s no config', () => { - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au']}); - submods.forEach(submod => sinon.assert.calledWith(submod.onAuctionConfig, auctionId, {au: null})); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: ['au'] }); + submods.forEach(submod => sinon.assert.calledWith(submod.onAuctionConfig, auctionId, { au: null })); }); it('is invoked with relevant configs', () => { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au1'}, paapiConfig); - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au2'}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: ['au1', 'au2', 'au3']}); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au1' }, paapiConfig); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au2' }, paapiConfig); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: ['au1', 'au2', 'au3'] }); submods.forEach(submod => { sinon.assert.calledWith(submod.onAuctionConfig, auctionId, { - au1: {componentAuctions: [auctionConfig]}, - au2: {componentAuctions: [auctionConfig]}, + au1: { componentAuctions: [auctionConfig] }, + au2: { componentAuctions: [auctionConfig] }, au3: null }); }); @@ -386,24 +386,24 @@ describe('paapi module', () => { Object.entries({ 'bids': (payload, values) => { payload.bidsReceived = values - .map((val) => ({adUnitCode: 'au', cpm: val.amount, currency: val.cur})) - .concat([{adUnitCode: 'other', cpm: 10000, currency: 'EUR'}]); + .map((val) => ({ adUnitCode: 'au', cpm: val.amount, currency: val.cur })) + .concat([{ adUnitCode: 'other', cpm: 10000, currency: 'EUR' }]); }, 'no bids': (payload, values) => { payload.bidderRequests = values .map((val) => ({ bids: [{ adUnitCode: 'au', - getFloor: () => ({floor: val.amount, currency: val.cur}) + getFloor: () => ({ floor: val.amount, currency: val.cur }) }] })) - .concat([{bids: {adUnitCode: 'other', getFloor: () => ({floor: -10000, currency: 'EUR'})}}]); + .concat([{ bids: { adUnitCode: 'other', getFloor: () => ({ floor: -10000, currency: 'EUR' }) } }]); } }).forEach(([tcase, setup]) => { describe(`when auction has ${tcase}`, () => { Object.entries({ 'no currencies': { - values: [{amount: 1}, {amount: 100}, {amount: 10}, {amount: 100}], + values: [{ amount: 1 }, { amount: 100 }, { amount: 10 }, { amount: 100 }], 'bids': { bidfloor: 100, bidfloorcur: undefined @@ -414,7 +414,7 @@ describe('paapi module', () => { } }, 'only zero values': { - values: [{amount: 0, cur: 'USD'}, {amount: 0, cur: 'JPY'}], + values: [{ amount: 0, cur: 'USD' }, { amount: 0, cur: 'JPY' }], 'bids': { bidfloor: undefined, bidfloorcur: undefined, @@ -425,7 +425,7 @@ describe('paapi module', () => { } }, 'matching currencies': { - values: [{amount: 10, cur: 'JPY'}, {amount: 100, cur: 'JPY'}], + values: [{ amount: 10, cur: 'JPY' }, { amount: 100, cur: 'JPY' }], 'bids': { bidfloor: 100, bidfloorcur: 'JPY', @@ -436,7 +436,7 @@ describe('paapi module', () => { } }, 'mixed currencies': { - values: [{amount: 10, cur: 'USD'}, {amount: 10, cur: 'JPY'}], + values: [{ amount: 10, cur: 'USD' }, { amount: 10, cur: 'JPY' }], 'bids': { bidfloor: 10, bidfloorcur: 'USD' @@ -448,19 +448,19 @@ describe('paapi module', () => { } }).forEach(([t, testConfig]) => { const values = testConfig.values; - const {bidfloor, bidfloorcur} = testConfig[tcase]; + const { bidfloor, bidfloorcur } = testConfig[tcase]; describe(`with ${t}`, () => { let payload; beforeEach(() => { - payload = {auctionId}; + payload = { auctionId }; setup(payload, values); }); it('should populate bidfloor/bidfloorcur', () => { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: 'au'}, paapiConfig); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: 'au' }, paapiConfig); events.emit(EVENTS.AUCTION_END, payload); - const cfg = getPAAPIConfig({auctionId}).au; + const cfg = getPAAPIConfig({ auctionId }).au; const signals = cfg.auctionSignals; sinon.assert.match(cfg.componentAuctions[0].auctionSignals, signals || {}); expect(signals?.prebid?.bidfloor).to.eql(bidfloor); @@ -481,8 +481,8 @@ describe('paapi module', () => { }); function getConfig() { - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode: adUnit.code}, paapiConfig); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: [adUnit.code], adUnits: [adUnit]}); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode: adUnit.code }, paapiConfig); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: [adUnit.code], adUnits: [adUnit] }); return getPAAPIConfig()[adUnit.code]; } @@ -507,7 +507,7 @@ describe('paapi module', () => { beforeEach(setup); it('without overriding component auctions, if set', () => { - auctionConfig.requestedSize = {width: '1px', height: '2px'}; + auctionConfig.requestedSize = { width: '1px', height: '2px' }; expect(getConfig().componentAuctions[0].requestedSize).to.eql({ width: '1px', height: '2px' @@ -555,75 +555,75 @@ describe('paapi module', () => { beforeEach(() => { const mockAuctions = [mockAuction(AUCTION1), mockAuction(AUCTION2)]; sandbox.stub(auctionManager, 'index').value(new AuctionIndex(() => mockAuctions)); - configs = {[AUCTION1]: {}, [AUCTION2]: {}}; + configs = { [AUCTION1]: {}, [AUCTION2]: {} }; Object.entries({ [AUCTION1]: [['au1', 'au2'], ['missing-1']], [AUCTION2]: [['au2', 'au3'], []], }).forEach(([auctionId, [adUnitCodes, noConfigAdUnitCodes]]) => { adUnitCodes.forEach(adUnitCode => { - const cfg = {...auctionConfig, auctionId, adUnitCode}; + const cfg = { ...auctionConfig, auctionId, adUnitCode }; configs[auctionId][adUnitCode] = cfg; - addPaapiConfigHook(nextFnSpy, {auctionId, adUnitCode}, {config: cfg}); + addPaapiConfigHook(nextFnSpy, { auctionId, adUnitCode }, { config: cfg }); }); - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: adUnitCodes.concat(noConfigAdUnitCodes)}); + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: adUnitCodes.concat(noConfigAdUnitCodes) }); }); }); it('should filter by auction', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2}), {au2: AUCTION2, au3: AUCTION2}); + expectAdUnitsFromAuctions(getPAAPIConfig({ auctionId: AUCTION1 }), { au1: AUCTION1, au2: AUCTION1 }); + expectAdUnitsFromAuctions(getPAAPIConfig({ auctionId: AUCTION2 }), { au2: AUCTION2, au3: AUCTION2 }); }); it('should filter by auction and ad unit', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1, adUnitCode: 'au2'}), {au2: AUCTION1}); - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION2, adUnitCode: 'au2'}), {au2: AUCTION2}); + expectAdUnitsFromAuctions(getPAAPIConfig({ auctionId: AUCTION1, adUnitCode: 'au2' }), { au2: AUCTION1 }); + expectAdUnitsFromAuctions(getPAAPIConfig({ auctionId: AUCTION2, adUnitCode: 'au2' }), { au2: AUCTION2 }); }); it('should use last auction for each ad unit', () => { - expectAdUnitsFromAuctions(getPAAPIConfig(), {au1: AUCTION1, au2: AUCTION2, au3: AUCTION2}); + expectAdUnitsFromAuctions(getPAAPIConfig(), { au1: AUCTION1, au2: AUCTION2, au3: AUCTION2 }); }); it('should filter by ad unit and use latest auction', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({adUnitCode: 'au2'}), {au2: AUCTION2}); + expectAdUnitsFromAuctions(getPAAPIConfig({ adUnitCode: 'au2' }), { au2: AUCTION2 }); }); it('should keep track of which configs were returned', () => { - expectAdUnitsFromAuctions(getPAAPIConfig({auctionId: AUCTION1}), {au1: AUCTION1, au2: AUCTION1}); - expect(getPAAPIConfig({auctionId: AUCTION1})).to.eql({}); - expectAdUnitsFromAuctions(getPAAPIConfig(), {au2: AUCTION2, au3: AUCTION2}); + expectAdUnitsFromAuctions(getPAAPIConfig({ auctionId: AUCTION1 }), { au1: AUCTION1, au2: AUCTION1 }); + expect(getPAAPIConfig({ auctionId: AUCTION1 })).to.eql({}); + expectAdUnitsFromAuctions(getPAAPIConfig(), { au2: AUCTION2, au3: AUCTION2 }); }); describe('includeBlanks = true', () => { Object.entries({ 'auction with blanks': { - filters: {auctionId: AUCTION1}, - expected: {au1: true, au2: true, 'missing-1': false} + filters: { auctionId: AUCTION1 }, + expected: { au1: true, au2: true, 'missing-1': false } }, 'blank adUnit in an auction': { - filters: {auctionId: AUCTION1, adUnitCode: 'missing-1'}, - expected: {'missing-1': false} + filters: { auctionId: AUCTION1, adUnitCode: 'missing-1' }, + expected: { 'missing-1': false } }, 'non-existing auction': { - filters: {auctionId: 'other'}, + filters: { auctionId: 'other' }, expected: {} }, 'non-existing adUnit in an auction': { - filters: {auctionId: AUCTION2, adUnitCode: 'other'}, + filters: { auctionId: AUCTION2, adUnitCode: 'other' }, expected: {} }, 'non-existing ad unit': { - filters: {adUnitCode: 'other'}, + filters: { adUnitCode: 'other' }, expected: {}, }, 'non existing ad unit in a non-existing auction': { - filters: {adUnitCode: 'other', auctionId: 'other'}, + filters: { adUnitCode: 'other', auctionId: 'other' }, expected: {} }, 'all ad units': { filters: {}, - expected: {'au1': true, 'au2': true, 'missing-1': false, 'au3': true} + expected: { 'au1': true, 'au2': true, 'missing-1': false, 'au3': true } } - }).forEach(([t, {filters, expected}]) => { + }).forEach(([t, { filters, expected }]) => { it(t, () => { const cfg = getPAAPIConfig(filters, true); expect(Object.keys(cfg)).to.have.members(Object.keys(expected)); @@ -755,7 +755,7 @@ describe('paapi module', () => { defaultForSlots: 1, } }); - await expectFledgeFlags({enabled: true, ae: 1}, {enabled: false, ae: 0}); + await expectFledgeFlags({ enabled: true, ae: 1 }, { enabled: false, ae: 0 }); }); it('should set paapi.enabled correctly for all bidders', async function () { @@ -766,7 +766,7 @@ describe('paapi module', () => { defaultForSlots: 1, } }); - await expectFledgeFlags({enabled: true, ae: 1}, {enabled: true, ae: 1}); + await expectFledgeFlags({ enabled: true, ae: 1 }, { enabled: true, ae: 1 }); }); Object.entries({ @@ -784,7 +784,7 @@ describe('paapi module', () => { }, componentSeller: true } - }).forEach(([t, {cfg, componentSeller}]) => { + }).forEach(([t, { cfg, componentSeller }]) => { it(`should set request paapi.componentSeller = ${componentSeller} when config componentSeller is ${t}`, () => { config.setConfig({ paapi: { @@ -823,7 +823,7 @@ describe('paapi module', () => { defaultForSlots: 1, } }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 0}}}); + Object.assign(adUnits[0], { ortb2Imp: { ext: { ae: 0 } } }); sinon.assert.match(getImpExt(), { global: { ae: 0, @@ -866,7 +866,7 @@ describe('paapi module', () => { enabled: true } }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 3}}}); + Object.assign(adUnits[0], { ortb2Imp: { ext: { ae: 3 } } }); sinon.assert.match(getImpExt(), { global: { ae: 3, @@ -886,7 +886,7 @@ describe('paapi module', () => { enabled: true } }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {ae: 1, igs: {biddable: 0}}}}); + Object.assign(adUnits[0], { ortb2Imp: { ext: { ae: 1, igs: { biddable: 0 } } } }); sinon.assert.match(getImpExt(), { global: { ae: 1, @@ -906,7 +906,7 @@ describe('paapi module', () => { enabled: true } }); - Object.assign(adUnits[0], {ortb2Imp: {ext: {igs: {}}}}); + Object.assign(adUnits[0], { ortb2Imp: { ext: { igs: {} } } }); sinon.assert.match(getImpExt(), { global: { ae: 1, @@ -1079,21 +1079,21 @@ describe('paapi module', () => { describe('partitionBuyersByBidder', () => { it('should split requests by bidder', () => { - expect(partitionBuyersByBidder([[{bidder: 'a'}, igb1], [{bidder: 'b'}, igb2]])).to.eql([ - [{bidder: 'a'}, [igb1]], - [{bidder: 'b'}, [igb2]] + expect(partitionBuyersByBidder([[{ bidder: 'a' }, igb1], [{ bidder: 'b' }, igb2]])).to.eql([ + [{ bidder: 'a' }, [igb1]], + [{ bidder: 'b' }, [igb2]] ]); }); it('accepts repeated buyers, if from different bidders', () => { expect(partitionBuyersByBidder([ - [{bidder: 'a', extra: 'data'}, igb1], - [{bidder: 'b', more: 'data'}, igb1], - [{bidder: 'a'}, igb2], - [{bidder: 'b'}, igb2] + [{ bidder: 'a', extra: 'data' }, igb1], + [{ bidder: 'b', more: 'data' }, igb1], + [{ bidder: 'a' }, igb2], + [{ bidder: 'b' }, igb2] ])).to.eql([ - [{bidder: 'a', extra: 'data'}, [igb1, igb2]], - [{bidder: 'b', more: 'data'}, [igb1, igb2]] + [{ bidder: 'a', extra: 'data' }, [igb1, igb2]], + [{ bidder: 'b', more: 'data' }, [igb1, igb2]] ]); }); describe('buyersToAuctionConfig', () => { @@ -1109,7 +1109,7 @@ describe('paapi module', () => { expand: sinon.stub(), }; let i = 0; - merge = sinon.stub().callsFake(() => ({config: i++})); + merge = sinon.stub().callsFake(() => ({ config: i++ })); igbRequests = [ [{}, igb1], [{}, igb2] @@ -1150,8 +1150,8 @@ describe('paapi module', () => { it('sets FPD in auction signals when partitioner returns it', () => { const fpd = { - ortb2: {fpd: 1}, - ortb2Imp: {fpd: 2} + ortb2: { fpd: 1 }, + ortb2Imp: { fpd: 2 } }; partitioners.compact.returns([[{}], [fpd]]); const [cf1, cf2] = toAuctionConfig(); @@ -1188,7 +1188,7 @@ describe('paapi module', () => { in: [[1, 1]], out: undefined } - }).forEach(([t, {in: input, out}]) => { + }).forEach(([t, { in: input, out }]) => { it(t, () => { expect(getPAAPISize(input)).to.eql(out); }); @@ -1200,7 +1200,7 @@ describe('paapi module', () => { beforeEach(() => { next = sinon.stub(); spec = {}; - bidderRequest = {paapi: {enabled: true}}; + bidderRequest = { paapi: { enabled: true } }; bids = []; }); @@ -1218,7 +1218,7 @@ describe('paapi module', () => { }, 'returns params, but PAAPI is disabled'() { bidderRequest.paapi.enabled = false; - spec.paapiParameters = () => ({param: new AsyncPAAPIParam()}) + spec.paapiParameters = () => ({ param: new AsyncPAAPIParam() }) } }).forEach(([t, setup]) => { it(`should do nothing if spec ${t}`, async () => { @@ -1294,7 +1294,7 @@ describe('paapi module', () => { bidderRequest = { auctionId: 'aid', bidderCode: 'mockBidder', - paapi: {enabled: true}, + paapi: { enabled: true }, bids, ortb2: { source: { @@ -1302,20 +1302,20 @@ describe('paapi module', () => { } } }; - restOfTheArgs = [{more: 'args'}]; + restOfTheArgs = [{ more: 'args' }]; mockConfig = { seller: 'mock.seller', decisionLogicURL: 'mock.seller/decisionLogic', interestGroupBuyers: ['mock.buyer'] } mockAuction = {}; - bidsReceived = [{adUnitCode: 'au', cpm: 1}]; - adUnits = [{code: 'au'}] + bidsReceived = [{ adUnitCode: 'au', cpm: 1 }]; + adUnits = [{ code: 'au' }] adUnitCodes = ['au']; bidderRequests = [bidderRequest]; sandbox.stub(auctionManager.index, 'getAuction').callsFake(() => mockAuction); sandbox.stub(auctionManager.index, 'getAdUnit').callsFake((req) => bids.find(bid => bid.adUnitCode === req.adUnitCode)) - config.setConfig({paapi: {enabled: true}}); + config.setConfig({ paapi: { enabled: true } }); }); afterEach(() => { @@ -1325,16 +1325,16 @@ describe('paapi module', () => { function startParallel() { parallelPaapiProcessing(next, spec, bids, bidderRequest, ...restOfTheArgs); - onAuctionInit({auctionId: 'aid'}) + onAuctionInit({ auctionId: 'aid' }) } function endAuction() { - events.emit(EVENTS.AUCTION_END, {auctionId: 'aid', bidsReceived, bidderRequests, adUnitCodes, adUnits}) + events.emit(EVENTS.AUCTION_END, { auctionId: 'aid', bidsReceived, bidderRequests, adUnitCodes, adUnits }) } describe('should have no effect when', () => { afterEach(() => { - expect(getPAAPIConfig({}, true)).to.eql({au: null}); + expect(getPAAPIConfig({}, true)).to.eql({ au: null }); }) it('spec has no buildPAAPIConfigs', () => { startParallel(); @@ -1342,16 +1342,16 @@ describe('paapi module', () => { Object.entries({ 'returns no configs': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => []); }, 'throws': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => { throw new Error() }) }, - 'returns too little config': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [ {bidId: 'bidId', config: {seller: 'mock.seller'}} ]) }, + 'returns too little config': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{ bidId: 'bidId', config: { seller: 'mock.seller' } }]) }, 'bidder is not paapi enabled': () => { bidderRequest.paapi.enabled = false; - spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{config: mockConfig, bidId: 'bidId'}]) + spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{ config: mockConfig, bidId: 'bidId' }]) }, 'paapi module is not enabled': () => { delete bidderRequest.paapi; - spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{config: mockConfig, bidId: 'bidId'}]) + spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{ config: mockConfig, bidId: 'bidId' }]) }, - 'bidId points to missing bid': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{config: mockConfig, bidId: 'missing'}]) } + 'bidId points to missing bid': () => { spec.buildPAAPIConfigs = sinon.stub().callsFake(() => [{ config: mockConfig, bidId: 'missing' }]) } }).forEach(([t, setup]) => { it(`buildPAAPIConfigs ${t}`, () => { setup(); @@ -1370,7 +1370,7 @@ describe('paapi module', () => { describe('when buildPAAPIConfigs returns valid config', () => { let builtCfg; beforeEach(() => { - builtCfg = [{bidId: 'bidId', config: mockConfig}]; + builtCfg = [{ bidId: 'bidId', config: mockConfig }]; spec.buildPAAPIConfigs = sinon.stub().callsFake(() => builtCfg); }); @@ -1407,7 +1407,7 @@ describe('paapi module', () => { }); it('should hide TIDs from buildPAAPIConfigs', () => { - config.setConfig({enableTIDs: false}); + config.setConfig({ enableTIDs: false }); startParallel(); sinon.assert.calledWith( spec.buildPAAPIConfigs, @@ -1417,7 +1417,7 @@ describe('paapi module', () => { }); it('should show TIDs when enabled', () => { - config.setConfig({enableTIDs: true}); + config.setConfig({ enableTIDs: true }); startParallel(); sinon.assert.calledWith( spec.buildPAAPIConfigs, @@ -1427,7 +1427,7 @@ describe('paapi module', () => { }) it('should respect requestedSize from adapter', () => { - mockConfig.requestedSize = {width: 1, height: 2}; + mockConfig.requestedSize = { width: 1, height: 2 }; startParallel(); sinon.assert.match(getPAAPIConfig().au, { requestedSize: { @@ -1455,7 +1455,7 @@ describe('paapi module', () => { config = await resolveConfig(config); sinon.assert.match(config, { auctionSignals: { - prebid: {bidfloor: 1} + prebid: { bidfloor: 1 } } }) }); @@ -1464,12 +1464,12 @@ describe('paapi module', () => { let configRemainder; beforeEach(() => { configRemainder = { - ...Object.fromEntries(ASYNC_SIGNALS.map(signal => [signal, {type: signal}])), + ...Object.fromEntries(ASYNC_SIGNALS.map(signal => [signal, { type: signal }])), seller: 'mock.seller' }; }) function returnRemainder() { - addPaapiConfigHook(sinon.stub(), bids[0], {config: configRemainder}); + addPaapiConfigHook(sinon.stub(), bids[0], { config: configRemainder }); } it('should resolve component configs with values returned by adapters', async () => { startParallel(); @@ -1484,7 +1484,7 @@ describe('paapi module', () => { startParallel(); let config = getPAAPIConfig().au.componentAuctions[0]; returnRemainder(); - const expectedSignals = {...configRemainder}; + const expectedSignals = { ...configRemainder }; configRemainder = { ...configRemainder, auctionSignals: { @@ -1499,7 +1499,7 @@ describe('paapi module', () => { describe('should default to values returned from buildPAAPIConfigs when interpretResponse does not return', () => { beforeEach(() => { - ASYNC_SIGNALS.forEach(signal => mockConfig[signal] = {default: signal}) + ASYNC_SIGNALS.forEach(signal => mockConfig[signal] = { default: signal }) }); Object.entries({ 'returns no matching config'() { @@ -1532,21 +1532,21 @@ describe('paapi module', () => { [ { - start: {t: 'scalar', value: 'str'}, - end: {t: 'array', value: ['abc']}, - should: {t: 'array', value: ['abc']} + start: { t: 'scalar', value: 'str' }, + end: { t: 'array', value: ['abc'] }, + should: { t: 'array', value: ['abc'] } }, { - start: {t: 'object', value: {a: 'b'}}, - end: {t: 'scalar', value: 'abc'}, - should: {t: 'scalar', value: 'abc'} + start: { t: 'object', value: { a: 'b' } }, + end: { t: 'scalar', value: 'abc' }, + should: { t: 'scalar', value: 'abc' } }, { - start: {t: 'object', value: {outer: {inner: 'val'}}}, - end: {t: 'object', value: {outer: {other: 'val'}}}, - should: {t: 'merge', value: {outer: {inner: 'val', other: 'val'}}} + start: { t: 'object', value: { outer: { inner: 'val' } } }, + end: { t: 'object', value: { outer: { other: 'val' } } }, + should: { t: 'merge', value: { outer: { inner: 'val', other: 'val' } } } } - ].forEach(({start, end, should}) => { + ].forEach(({ start, end, should }) => { it(`when buildPAAPIConfigs returns ${start.t}, interpretResponse return ${end.t}, promise should resolve to ${should.t}`, async () => { mockConfig.sellerSignals = start.value startParallel(); @@ -1562,7 +1562,7 @@ describe('paapi module', () => { it('should make extra configs available', async () => { startParallel(); returnRemainder(); - configRemainder = {...configRemainder, seller: 'other.seller'}; + configRemainder = { ...configRemainder, seller: 'other.seller' }; returnRemainder(); endAuction(); let configs = getPAAPIConfig().au.componentAuctions; @@ -1574,30 +1574,30 @@ describe('paapi module', () => { let onAuctionConfig; beforeEach(() => { onAuctionConfig = sinon.stub(); - registerSubmodule({onAuctionConfig}) + registerSubmodule({ onAuctionConfig }) }); Object.entries({ 'parallel=true, some configs deferred': { setup() { - config.mergeConfig({paapi: {parallel: true}}) + config.mergeConfig({ paapi: { parallel: true } }) }, delayed: false, }, 'parallel=true, no deferred configs': { setup() { - config.mergeConfig({paapi: {parallel: true}}); + config.mergeConfig({ paapi: { parallel: true } }); spec.buildPAAPIConfigs = sinon.stub().callsFake(() => []); }, delayed: true }, 'parallel=false, some configs deferred': { setup() { - config.mergeConfig({paapi: {parallel: false}}) + config.mergeConfig({ paapi: { parallel: false } }) }, delayed: true } - }).forEach(([t, {setup, delayed}]) => { + }).forEach(([t, { setup, delayed }]) => { describe(`when ${t}`, () => { beforeEach(() => { mockAuction.requestsDone = Promise.resolve(); @@ -1629,8 +1629,8 @@ describe('paapi module', () => { describe('when buildPAAPIConfigs returns igb', () => { let builtCfg, igb, auctionConfig; beforeEach(() => { - igb = {origin: 'mock.buyer'} - builtCfg = [{bidId: 'bidId', igb}]; + igb = { origin: 'mock.buyer' } + builtCfg = [{ bidId: 'bidId', igb }]; spec.buildPAAPIConfigs = sinon.stub().callsFake(() => builtCfg); auctionConfig = { seller: 'mock.seller', @@ -1653,7 +1653,7 @@ describe('paapi module', () => { builtCfg = [] }, 'returned igb is not valid'() { - builtCfg = [{bidId: 'bidId', igb: {}}]; + builtCfg = [{ bidId: 'bidId', igb: {} }]; } }).forEach(([t, setup]) => { it(`should have no effect when ${t}`, () => { @@ -1673,9 +1673,9 @@ describe('paapi module', () => { }); it('should use signal values from componentSeller.auctionConfig', async () => { - auctionConfig.auctionSignals = {test: 'signal'}; + auctionConfig.auctionSignals = { test: 'signal' }; config.mergeConfig({ - paapi: {componentSeller: {auctionConfig}} + paapi: { componentSeller: { auctionConfig } } }) startParallel(); endAuction(); @@ -1692,23 +1692,23 @@ describe('paapi module', () => { }); function returnIgb(igb) { - addPaapiConfigHook(sinon.stub(), bids[0], {igb}); + addPaapiConfigHook(sinon.stub(), bids[0], { igb }); } it('should resolve to values from interpretResponse as well as buildPAAPIConfigs', async () => { igb.cur = 'cur'; - igb.pbs = {over: 'ridden'} + igb.pbs = { over: 'ridden' } startParallel(); let cfg = getPAAPIConfig().au.componentAuctions[0]; returnIgb({ origin: 'mock.buyer', - pbs: {some: 'signal'} + pbs: { some: 'signal' } }); endAuction(); cfg = await resolveConfig(cfg); sinon.assert.match(cfg, { perBuyerSignals: { - [igb.origin]: {some: 'signal'}, + [igb.origin]: { some: 'signal' }, }, perBuyerCurrencies: { [igb.origin]: 'cur' @@ -1736,18 +1736,18 @@ describe('paapi module', () => { let cfg = getPAAPIConfig().au.componentAuctions[0]; returnIgb({ origin: 'mock.buyer', - pbs: {signal: 1} + pbs: { signal: 1 } }); returnIgb({ origin: 'other.buyer', - pbs: {signal: 2} + pbs: { signal: 2 } }); endAuction(); cfg = await resolveConfig(cfg); sinon.assert.match(cfg, { perBuyerSignals: { - 'mock.buyer': {signal: 1}, - 'other.buyer': {signal: 2} + 'mock.buyer': { signal: 1 }, + 'other.buyer': { signal: 2 } }, perBuyerCurrencies: { 'mock.buyer': 'cur1', @@ -1810,14 +1810,14 @@ describe('paapi module', () => { describe('ortb processors for fledge', () => { it('imp.ext.ae should be removed if fledge is not enabled', () => { - const imp = {ext: {ae: 1, igs: {}}}; - setImpExtAe(imp, {}, {bidderRequest: {}}); + const imp = { ext: { ae: 1, igs: {} } }; + setImpExtAe(imp, {}, { bidderRequest: {} }); expect(imp.ext.ae).to.not.exist; expect(imp.ext.igs).to.not.exist; }); it('imp.ext.ae should be left intact if fledge is enabled', () => { - const imp = {ext: {ae: 2, igs: {biddable: 0}}}; - setImpExtAe(imp, {}, {bidderRequest: {paapi: {enabled: true}}}); + const imp = { ext: { ae: 2, igs: { biddable: 0 } } }; + setImpExtAe(imp, {}, { bidderRequest: { paapi: { enabled: true } } }); expect(imp.ext).to.eql({ ae: 2, igs: { @@ -1828,7 +1828,7 @@ describe('paapi module', () => { describe('response parsing', () => { function generateImpCtx(fledgeFlags) { - return Object.fromEntries(Object.entries(fledgeFlags).map(([impid, fledgeEnabled]) => [impid, {imp: {ext: {ae: fledgeEnabled}}}])); + return Object.fromEntries(Object.entries(fledgeFlags).map(([impid, fledgeEnabled]) => [impid, { imp: { ext: { ae: fledgeEnabled } } }])); } function extractResult(type, ctx) { @@ -1894,17 +1894,17 @@ describe('paapi module', () => { } } } - }).forEach(([t, {parser, responses}]) => { + }).forEach(([t, { parser, responses }]) => { describe(t, () => { Object.entries(responses).forEach(([t, packageConfigs]) => { describe(`when response uses ${t}`, () => { function generateCfg(impid, ...ids) { - return ids.map((id) => ({impid, config: {id}})); + return ids.map((id) => ({ impid, config: { id } })); } it('should collect auction configs by imp', () => { const ctx = { - impContext: generateImpCtx({e1: 1, e2: 1, d1: 0}) + impContext: generateImpCtx({ e1: 1, e2: 1, d1: 0 }) }; const resp = packageConfigs( generateCfg('e1', 1, 2, 3) @@ -1918,7 +1918,7 @@ describe('paapi module', () => { }); }); it('should not choke if fledge config references unknown imp', () => { - const ctx = {impContext: generateImpCtx({i: 1})}; + const ctx = { impContext: generateImpCtx({ i: 1 }) }; const resp = packageConfigs(generateCfg('unknown', 1)); parser({}, resp, ctx); expect(extractResult('config', ctx.impContext)).to.eql({}); @@ -1931,7 +1931,7 @@ describe('paapi module', () => { describe('response ext.igi.igb', () => { it('should collect igb by imp', () => { const ctx = { - impContext: generateImpCtx({e1: 1, e2: 1, d1: 0}) + impContext: generateImpCtx({ e1: 1, e2: 1, d1: 0 }) }; const resp = { ext: { @@ -1939,20 +1939,20 @@ describe('paapi module', () => { { impid: 'e1', igb: [ - {id: 1}, - {id: 2} + { id: 1 }, + { id: 2 } ] }, { impid: 'e2', igb: [ - {id: 3} + { id: 3 } ] }, { impid: 'd1', igb: [ - {id: 4} + { id: 4 } ] } ] @@ -1972,29 +1972,29 @@ describe('paapi module', () => { const ctx = { impContext: { 1: { - bidRequest: {bidId: 'bid1'}, - paapiConfigs: [{config: {id: 1}}, {config: {id: 2}}] + bidRequest: { bidId: 'bid1' }, + paapiConfigs: [{ config: { id: 1 } }, { config: { id: 2 } }] }, 2: { - bidRequest: {bidId: 'bid2'}, - paapiConfigs: [{config: {id: 3}}] + bidRequest: { bidId: 'bid2' }, + paapiConfigs: [{ config: { id: 3 } }] }, 3: { - bidRequest: {bidId: 'bid3'} + bidRequest: { bidId: 'bid3' } }, 4: { - bidRequest: {bidId: 'bid1'}, - paapiConfigs: [{igb: {id: 4}}] + bidRequest: { bidId: 'bid1' }, + paapiConfigs: [{ igb: { id: 4 } }] } } }; const resp = {}; setResponsePaapiConfigs(resp, {}, ctx); expect(resp.paapi).to.eql([ - {bidId: 'bid1', config: {id: 1}}, - {bidId: 'bid1', config: {id: 2}}, - {bidId: 'bid2', config: {id: 3}}, - {bidId: 'bid1', igb: {id: 4}} + { bidId: 'bid1', config: { id: 1 } }, + { bidId: 'bid1', config: { id: 2 } }, + { bidId: 'bid2', config: { id: 3 } }, + { bidId: 'bid1', igb: { id: 4 } } ]); }); it('should not set paapi if no config or igb exists', () => { diff --git a/test/spec/modules/padsquadBidAdapter_spec.js b/test/spec/modules/padsquadBidAdapter_spec.js index 1229ce778ff..73ccd0e2e2c 100644 --- a/test/spec/modules/padsquadBidAdapter_spec.js +++ b/test/spec/modules/padsquadBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/padsquadBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/padsquadBidAdapter.js'; const REQUEST = { 'bidderCode': 'padsquad', @@ -219,7 +219,7 @@ describe('Padsquad bid adapter', function () { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, RESPONSE, {'body': {}}); + const EMPTY_RESP = Object.assign({}, RESPONSE, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, REQUEST); expect(bids).to.be.empty; @@ -232,13 +232,13 @@ describe('Padsquad bid adapter', function () { expect(opts).to.be.an('array').that.is.empty; }); it('returns non if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('iframe sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [RESPONSE]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('iframe'); @@ -246,7 +246,7 @@ describe('Padsquad bid adapter', function () { }); it('pixel sync enabled should return results', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [RESPONSE]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('image'); @@ -254,7 +254,7 @@ describe('Padsquad bid adapter', function () { }); it('all sync enabled should return all results', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [RESPONSE]); + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [RESPONSE]); expect(opts.length).to.equal(2); }); diff --git a/test/spec/modules/pairIdSystem_spec.js b/test/spec/modules/pairIdSystem_spec.js index 1228100f3f8..ae297ad61ca 100644 --- a/test/spec/modules/pairIdSystem_spec.js +++ b/test/spec/modules/pairIdSystem_spec.js @@ -23,7 +23,7 @@ describe('pairId', function () { sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('pairId').returns(btoa(JSON.stringify(pairIds))); const id = pairIdSubmodule.getId({ params: {} }); - expect(id).to.be.deep.equal({id: pairIds}); + expect(id).to.be.deep.equal({ id: pairIds }); }); it('should read pairId from cookie if exists', function() { @@ -31,39 +31,42 @@ describe('pairId', function () { sandbox.stub(storage, 'getCookie').withArgs('pairId').returns(btoa(JSON.stringify(pairIds))); const id = pairIdSubmodule.getId({ params: {} }); - expect(id).to.be.deep.equal({id: pairIds}); + expect(id).to.be.deep.equal({ id: pairIds }); }); it('should read pairId from default liveramp envelope local storage key if configured', function() { const pairIds = ['test-pair-id1', 'test-pair-id2', 'test-pair-id3']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': pairIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({ 'envelope': pairIds }))); const id = pairIdSubmodule.getId({ params: { liveramp: {} - }}) - expect(id).to.be.deep.equal({id: pairIds}) + } + }) + expect(id).to.be.deep.equal({ id: pairIds }) }) it('should read pairId from default liveramp envelope cookie entry if configured', function() { const pairIds = ['test-pair-id4', 'test-pair-id5', 'test-pair-id6']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({'envelope': pairIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('_lr_pairId').returns(btoa(JSON.stringify({ 'envelope': pairIds }))); const id = pairIdSubmodule.getId({ params: { liveramp: {} - }}) - expect(id).to.be.deep.equal({id: pairIds}) + } + }) + expect(id).to.be.deep.equal({ id: pairIds }) }) it('should read pairId from specified liveramp envelope cookie entry if configured with storageKey', function() { const pairIds = ['test-pair-id7', 'test-pair-id8', 'test-pair-id9']; - sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('lr_pairId_custom').returns(btoa(JSON.stringify({'envelope': pairIds}))); + sandbox.stub(storage, 'getDataFromLocalStorage').withArgs('lr_pairId_custom').returns(btoa(JSON.stringify({ 'envelope': pairIds }))); const id = pairIdSubmodule.getId({ params: { liveramp: { storageKey: 'lr_pairId_custom' } - }}) - expect(id).to.be.deep.equal({id: pairIds}) + } + }) + expect(id).to.be.deep.equal({ id: pairIds }) }) it('should not get data from storage if local storage and cookies are disabled', function () { diff --git a/test/spec/modules/panxoRtdProvider_spec.js b/test/spec/modules/panxoRtdProvider_spec.js new file mode 100644 index 00000000000..d3e0cbe12bf --- /dev/null +++ b/test/spec/modules/panxoRtdProvider_spec.js @@ -0,0 +1,311 @@ +import { loadExternalScriptStub } from 'test/mocks/adloaderStub.js'; + +import * as utils from '../../../src/utils.js'; +import * as hook from '../../../src/hook.js'; +import * as refererDetection from '../../../src/refererDetection.js'; + +import { __TEST__ } from '../../../modules/panxoRtdProvider.js'; + +const { + SUBMODULE_NAME, + SCRIPT_URL, + main, + load, + onImplLoaded, + onImplMessage, + onGetBidRequestData, + flushPendingCallbacks +} = __TEST__; + +describe('panxo RTD module', function () { + let sandbox; + + const stubUuid = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; + const panxoBridgeId = `panxo_${stubUuid}`; + const stubWindow = { [panxoBridgeId]: undefined }; + + const validSiteId = 'a1b2c3d4e5f67890'; + + beforeEach(function() { + sandbox = sinon.createSandbox(); + sandbox.stub(utils, 'getWindowSelf').returns(stubWindow); + sandbox.stub(utils, 'generateUUID').returns(stubUuid); + sandbox.stub(refererDetection, 'getRefererInfo').returns({ domain: 'example.com' }); + }); + afterEach(function() { + sandbox.restore(); + }); + + describe('Initialization step', function () { + let sandbox2; + let connectSpy; + beforeEach(function() { + sandbox2 = sinon.createSandbox(); + connectSpy = sandbox.spy(); + // Simulate: once the impl script is loaded, it registers the bridge API + sandbox2.stub(stubWindow, panxoBridgeId).value({ connect: connectSpy }); + }); + afterEach(function () { + sandbox2.restore(); + }); + + it('should accept valid configuration with siteId', function () { + expect(() => load({ params: { siteId: validSiteId } })).to.not.throw(); + }); + + it('should throw an Error when siteId is missing', function () { + expect(() => load({})).to.throw(); + expect(() => load({ params: {} })).to.throw(); + expect(() => load({ params: { siteId: '' } })).to.throw(); + }); + + it('should throw an Error when siteId is not a valid hex string', function () { + expect(() => load({ params: { siteId: 'abc' } })).to.throw(); + expect(() => load({ params: { siteId: 123 } })).to.throw(); + expect(() => load({ params: { siteId: 'zzzzzzzzzzzzzzzz' } })).to.throw(); + expect(() => load({ params: { siteId: 'a1b2c3d4e5f6789' } })).to.throw(); // 15 chars + expect(() => load({ params: { siteId: 'a1b2c3d4e5f678901' } })).to.throw(); // 17 chars + }); + + it('should insert implementation script with correct URL', () => { + load({ params: { siteId: validSiteId } }); + + expect(loadExternalScriptStub.calledOnce).to.be.true; + + const args = loadExternalScriptStub.getCall(0).args; + expect(args[0]).to.be.equal( + `${SCRIPT_URL}?siteId=${validSiteId}&session=${stubUuid}&r=example.com` + ); + expect(args[2]).to.be.equal(SUBMODULE_NAME); + expect(args[3]).to.be.equal(onImplLoaded); + }); + + it('should connect to the implementation script once it loads', function () { + load({ params: { siteId: validSiteId } }); + + expect(loadExternalScriptStub.calledOnce).to.be.true; + expect(connectSpy.calledOnce).to.be.true; + + const args = connectSpy.getCall(0).args; + expect(args[0]).to.haveOwnProperty('cmd'); // pbjs global + expect(args[0]).to.haveOwnProperty('que'); + expect(args[1]).to.be.equal(onImplMessage); + }); + + it('should flush pending callbacks when bridge is unavailable', function () { + sandbox2.restore(); + // Bridge is not registered on the window -- onImplLoaded should fail open + sandbox2 = sinon.createSandbox(); + sandbox2.stub(stubWindow, panxoBridgeId).value(undefined); + + load({ params: { siteId: validSiteId } }); + + const callbackSpy = sandbox2.spy(); + const reqBidsConfig = { ortb2Fragments: { bidder: {}, global: {} } }; + + // Queue a callback before bridge fails + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + // onImplLoaded already ran (bridge undefined) and flushed + expect(callbackSpy.calledOnce).to.be.true; + }); + + it('should not throw when bridge message is null', function () { + load({ params: { siteId: validSiteId } }); + expect(() => onImplMessage(null)).to.not.throw(); + expect(() => onImplMessage(undefined)).to.not.throw(); + }); + }); + + describe('Bid enrichment step', function () { + const signalData = { + device: { v1: 'session-token-123' }, + site: { ai: true, src: 'chatgpt', conf: 0.95, seg: 'technology', co: 'US' } + }; + + let sandbox2; + let callbackSpy; + let reqBidsConfig; + beforeEach(function() { + sandbox2 = sinon.createSandbox(); + callbackSpy = sandbox2.spy(); + reqBidsConfig = { ortb2Fragments: { bidder: {}, global: {} } }; + // Prevent onImplLoaded from firing automatically so tests can + // control module readiness via onImplMessage directly. + loadExternalScriptStub.callsFake(() => {}); + }); + afterEach(function () { + loadExternalScriptStub.reset(); + sandbox2.restore(); + }); + + it('should defer callback when implementation has not sent a signal yet', () => { + load({ params: { siteId: validSiteId } }); + + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + + // Callback is deferred until the implementation script sends its first signal + expect(callbackSpy.notCalled).to.be.true; + }); + + it('should flush deferred callback once a signal arrives', () => { + load({ params: { siteId: validSiteId } }); + + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + expect(callbackSpy.notCalled).to.be.true; + + // First signal arrives -- deferred callback should now fire + onImplMessage({ type: 'signal', data: { device: { v1: 'tok' }, site: {} } }); + expect(callbackSpy.calledOnce).to.be.true; + }); + + it('should flush all deferred callbacks when the first signal arrives', () => { + load({ params: { siteId: validSiteId } }); + + const spy1 = sandbox2.spy(); + const spy2 = sandbox2.spy(); + const cfg1 = { ortb2Fragments: { bidder: {}, global: {} } }; + const cfg2 = { ortb2Fragments: { bidder: {}, global: {} } }; + + onGetBidRequestData(cfg1, spy1, { params: {} }, {}); + onGetBidRequestData(cfg2, spy2, { params: {} }, {}); + expect(spy1.notCalled).to.be.true; + expect(spy2.notCalled).to.be.true; + + onImplMessage({ type: 'signal', data: { device: { v1: 'tok' }, site: {} } }); + expect(spy1.calledOnce).to.be.true; + expect(spy2.calledOnce).to.be.true; + }); + + it('should call callback immediately once implementation is ready', () => { + load({ params: { siteId: validSiteId } }); + + // Mark implementation as ready via a signal + onImplMessage({ type: 'signal', data: { device: { v1: 'tok' }, site: {} } }); + + // Subsequent calls should resolve immediately + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + expect(callbackSpy.calledOnce).to.be.true; + }); + + it('should call callback when implementation reports an error', () => { + load({ params: { siteId: validSiteId } }); + + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + expect(callbackSpy.notCalled).to.be.true; + + // An error still unblocks the auction + onImplMessage({ type: 'error', data: 'some error' }); + expect(callbackSpy.calledOnce).to.be.true; + // No device or site should be added since panxoData is empty + }); + + it('should add device.ext.panxo with session token when signal is received', () => { + load({ params: { siteId: validSiteId } }); + + onImplMessage({ type: 'signal', data: signalData }); + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + + expect(callbackSpy.calledOnce).to.be.true; + expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('device'); + expect(reqBidsConfig.ortb2Fragments.global.device).to.have.own.property('ext'); + expect(reqBidsConfig.ortb2Fragments.global.device.ext).to.have.own.property('panxo') + .which.is.an('object') + .that.deep.equals(signalData.device); + }); + + it('should add site.ext.data.panxo with AI classification data', () => { + load({ params: { siteId: validSiteId } }); + + onImplMessage({ type: 'signal', data: signalData }); + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + + expect(callbackSpy.calledOnce).to.be.true; + expect(reqBidsConfig.ortb2Fragments.global).to.have.own.property('site'); + expect(reqBidsConfig.ortb2Fragments.global.site).to.have.own.property('ext'); + expect(reqBidsConfig.ortb2Fragments.global.site.ext).to.have.own.property('data'); + expect(reqBidsConfig.ortb2Fragments.global.site.ext.data).to.have.own.property('panxo') + .which.is.an('object') + .that.deep.equals(signalData.site); + }); + + it('should update panxo data when new signal is received', () => { + load({ params: { siteId: validSiteId } }); + + const updatedData = { + device: { v1: 'updated-token' }, + site: { ai: true, src: 'perplexity', conf: 0.88, seg: 'finance', co: 'UK' } + }; + + onImplMessage({ type: 'signal', data: { device: { v1: 'old-token' }, site: {} } }); + onImplMessage({ type: 'signal', data: updatedData }); + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + + expect(callbackSpy.calledOnce).to.be.true; + expect(reqBidsConfig.ortb2Fragments.global.device.ext.panxo) + .to.deep.equal(updatedData.device); + expect(reqBidsConfig.ortb2Fragments.global.site.ext.data.panxo) + .to.deep.equal(updatedData.site); + }); + + it('should not add site data when site object is empty', () => { + load({ params: { siteId: validSiteId } }); + + onImplMessage({ type: 'signal', data: { device: { v1: 'token' }, site: {} } }); + onGetBidRequestData(reqBidsConfig, callbackSpy, { params: {} }, {}); + + expect(callbackSpy.calledOnce).to.be.true; + expect(reqBidsConfig.ortb2Fragments.global.device.ext.panxo) + .to.deep.equal({ v1: 'token' }); + // site should not have panxo data since it was empty + expect(reqBidsConfig.ortb2Fragments.global).to.not.have.own.property('site'); + }); + }); + + describe('Submodule execution', function() { + let sandbox2; + let submoduleStub; + beforeEach(function() { + sandbox2 = sinon.createSandbox(); + submoduleStub = sandbox2.stub(hook, 'submodule'); + }); + afterEach(function () { + sandbox2.restore(); + }); + + function getModule() { + main(); + + expect(submoduleStub.calledOnceWith('realTimeData')).to.equal(true); + + const submoduleDef = submoduleStub.getCall(0).args[1]; + expect(submoduleDef).to.be.an('object'); + expect(submoduleDef).to.have.own.property('name', SUBMODULE_NAME); + expect(submoduleDef).to.have.own.property('init').that.is.a('function'); + expect(submoduleDef).to.have.own.property('getBidRequestData').that.is.a('function'); + + return submoduleDef; + } + + it('should register panxo RTD submodule provider', function () { + getModule(); + }); + + it('should refuse initialization when siteId is missing', function () { + const { init } = getModule(); + expect(init({ params: {} })).to.equal(false); + expect(loadExternalScriptStub.notCalled).to.be.true; + }); + + it('should refuse initialization when siteId is invalid', function () { + const { init } = getModule(); + expect(init({ params: { siteId: 'invalid' } })).to.equal(false); + expect(loadExternalScriptStub.notCalled).to.be.true; + }); + + it('should commence initialization with valid siteId', function () { + const { init } = getModule(); + expect(init({ params: { siteId: validSiteId } })).to.equal(true); + expect(loadExternalScriptStub.calledOnce).to.be.true; + }); + }); +}); diff --git a/test/spec/modules/performaxBidAdapter_spec.js b/test/spec/modules/performaxBidAdapter_spec.js index 218f9402e75..e71ac16eb68 100644 --- a/test/spec/modules/performaxBidAdapter_spec.js +++ b/test/spec/modules/performaxBidAdapter_spec.js @@ -14,7 +14,9 @@ describe('Performax adapter', function () { banner: { sizes: [ [300, 300], - ]}}, + ] + } + }, adUnitCode: 'postbid_iframe', transactionId: '84deda92-e9ba-4b0d-a797-43be5e522430', adUnitId: '4ee4643b-931f-4a17-a571-ccba57886dc8', @@ -47,7 +49,9 @@ describe('Performax adapter', function () { banner: { sizes: [ [300, 600], - ]}}, + ] + } + }, adUnitCode: 'postbid_halfpage_iframe', transactionId: '84deda92-e9ba-4b0d-a797-43be5e522430', adUnitId: '4ee4643b-931f-4a17-a571-ccba57886dc8', @@ -65,7 +69,8 @@ describe('Performax adapter', function () { source: {}, site: {}, device: {} - }}]; + } + }]; const bidderRequest = { bidderCode: 'performax2', @@ -77,7 +82,8 @@ describe('Performax adapter', function () { regs: { ext: { gdpr: 1 - }}, + } + }, user: { ext: { consent: 'consent-string' @@ -85,7 +91,8 @@ describe('Performax adapter', function () { }, site: {}, device: {} - }}; + } + }; const serverResponse = { body: { @@ -101,20 +108,22 @@ describe('Performax adapter', function () { h: 300, adm: 'My ad' } - ]}]}, + ] + }] + }, } describe('isBidRequestValid', function () { const bid = {}; it('should return false when missing "tagid" param', function() { - bid.params = {slotId: 'param'}; + bid.params = { slotId: 'param' }; expect(spec.isBidRequestValid(bid)).to.equal(false); bid.params = {}; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should return true when tagid is correct', function() { - bid.params = {tagid: 'sample'}; + bid.params = { tagid: 'sample' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); }) @@ -131,31 +140,31 @@ describe('Performax adapter', function () { it('should pass correct imp', function () { const requests = spec.buildRequests([bids[0]], bidderRequest); - const {data} = requests[0]; - const {imp} = data; + const { data } = requests[0]; + const { imp } = data; expect(imp).to.be.an('array').that.has.lengthOf(1); expect(imp[0]).to.be.an('object'); const bid = imp[0]; expect(bid.id).to.equal('2bc545c347dbbe'); - expect(bid.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 300}]}); + expect(bid.banner).to.deep.equal({ topframe: 0, format: [{ w: 300, h: 300 }] }); }); it('should process multiple bids', function () { const requests = spec.buildRequests(bids, bidderRequest); expect(requests).to.be.an('array').that.has.lengthOf(1); - const {data} = requests[0]; - const {imp} = data; + const { data } = requests[0]; + const { imp } = data; expect(imp).to.be.an('array').that.has.lengthOf(bids.length); const bid1 = imp[0]; - expect(bid1.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 300}]}); + expect(bid1.banner).to.deep.equal({ topframe: 0, format: [{ w: 300, h: 300 }] }); const bid2 = imp[1]; - expect(bid2.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 600}]}); + expect(bid2.banner).to.deep.equal({ topframe: 0, format: [{ w: 300, h: 600 }] }); }); }); describe('interpretResponse', function () { it('should map params correctly', function () { - const ortbRequest = {data: converter.toORTB({bidderRequest, bids})}; + const ortbRequest = { data: converter.toORTB({ bidderRequest, bids }) }; serverResponse.body.id = ortbRequest.data.id; serverResponse.body.seatbid[0].bid[0].imp_id = ortbRequest.data.imp[0].id; diff --git a/test/spec/modules/permutiveCombined_spec.js b/test/spec/modules/permutiveCombined_spec.js index 244558d8378..1870c2161d4 100644 --- a/test/spec/modules/permutiveCombined_spec.js +++ b/test/spec/modules/permutiveCombined_spec.js @@ -1127,7 +1127,7 @@ describe('permutiveIdentityManagerIdSystem', () => { it('will optionally wait for Permutive SDK if no identities are in local storage already', async () => { const cleanup = setWindowPermutive() try { - const result = permutiveIdentityManagerIdSubmodule.getId({params: {ajaxTimeout: 300}}) + const result = permutiveIdentityManagerIdSubmodule.getId({ params: { ajaxTimeout: 300 } }) expect(result).not.to.be.undefined expect(result.id).to.be.undefined expect(result.callback).not.to.be.undefined diff --git a/test/spec/modules/pgamsspBidAdapter_spec.js b/test/spec/modules/pgamsspBidAdapter_spec.js index 6eea9bec92a..b881be50402 100644 --- a/test/spec/modules/pgamsspBidAdapter_spec.js +++ b/test/spec/modules/pgamsspBidAdapter_spec.js @@ -481,7 +481,7 @@ describe('PGAMBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -490,9 +490,7 @@ describe('PGAMBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.pgammedia.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -501,7 +499,7 @@ describe('PGAMBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.pgammedia.com/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js b/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js index ea0dd4ab793..d11e916d2b2 100644 --- a/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js +++ b/test/spec/modules/pianoDmpAnalyticsAdapter_spec.js @@ -53,7 +53,7 @@ describe('Piano DMP Analytics Adapter', () => { // Then const callQueue = (window.cX || {}).callQueue; - testEvents.forEach(({event, args}) => { + testEvents.forEach(({ event, args }) => { const [method, params] = callQueue.filter(item => item[1].eventType === event)[0]; expect(method).to.equal('prebid'); expect(params.params).to.deep.equal(args); diff --git a/test/spec/modules/pixfutureBidAdapter_spec.js b/test/spec/modules/pixfutureBidAdapter_spec.js index 78069c62441..1048b29718e 100644 --- a/test/spec/modules/pixfutureBidAdapter_spec.js +++ b/test/spec/modules/pixfutureBidAdapter_spec.js @@ -247,7 +247,7 @@ describe('PixFutureAdapter', function () { expect(bidRequest.data).to.exist; expect(bidRequest.data.sizes).to.deep.equal([[300, 250]]); - expect(bidRequest.data.params).to.deep.equal({'pix_id': '777'}); + expect(bidRequest.data.params).to.deep.equal({ 'pix_id': '777' }); expect(bidRequest.data.adUnitCode).to.deep.equal('26335x300x250x14x_ADSLOT88'); }); }); diff --git a/test/spec/modules/prebidServerBidAdapter_spec.js b/test/spec/modules/prebidServerBidAdapter_spec.js index 595b95c6db8..5e8cd74ec2e 100644 --- a/test/spec/modules/prebidServerBidAdapter_spec.js +++ b/test/spec/modules/prebidServerBidAdapter_spec.js @@ -1,21 +1,21 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { PrebidServer as Adapter, resetSyncedStatus, validateConfig, s2sDefaultConfig } from 'modules/prebidServerBidAdapter/index.js'; -import adapterManager, {PBS_ADAPTER_NAME} from 'src/adapterManager.js'; +import adapterManager, { PBS_ADAPTER_NAME } from 'src/adapterManager.js'; import * as utils from 'src/utils.js'; -import {deepAccess, deepClone, getWinDimensions, mergeDeep} from 'src/utils.js'; -import {ajax} from 'src/ajax.js'; -import {config} from 'src/config.js'; +import { deepAccess, deepClone, getWinDimensions, mergeDeep } from 'src/utils.js'; +import { ajax } from 'src/ajax.js'; +import { config } from 'src/config.js'; import * as events from 'src/events.js'; import { EVENTS, DEBUG_MODE } from 'src/constants.js'; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; import 'modules/appnexusBidAdapter.js'; // appnexus alias test import 'modules/rubiconBidAdapter.js'; // rubicon alias test -import {requestBids} from 'src/prebid.js'; +import { requestBids } from 'src/prebid.js'; import 'modules/currency.js'; // adServerCurrency test import 'modules/userId/index.js'; import 'modules/multibid/index.js'; @@ -26,22 +26,22 @@ import 'modules/consentManagementGpp.js'; import 'modules/paapi.js'; import * as redactor from 'src/activities/redactor.js'; import * as activityRules from 'src/activities/rules.js'; -import {hook} from '../../../src/hook.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; -import {auctionManager} from '../../../src/auctionManager.js'; -import {stubAuctionIndex} from '../../helpers/indexStub.js'; -import {addPaapiConfig, registerBidder} from 'src/adapters/bidderFactory.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {deepSetValue} from '../../../src/utils.js'; -import {ACTIVITY_TRANSMIT_UFPD} from '../../../src/activities/activities.js'; -import {MODULE_TYPE_PREBID} from '../../../src/activities/modules.js'; +import { hook } from '../../../src/hook.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { stubAuctionIndex } from '../../helpers/indexStub.js'; +import { addPaapiConfig, registerBidder } from 'src/adapters/bidderFactory.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { deepSetValue } from '../../../src/utils.js'; +import { ACTIVITY_TRANSMIT_UFPD } from '../../../src/activities/activities.js'; +import { MODULE_TYPE_PREBID } from '../../../src/activities/modules.js'; import { consolidateEids, extractEids, getPBSBidderConfig } from '../../../modules/prebidServerBidAdapter/bidderConfig.js'; -import {markWinningBid} from '../../../src/adRendering.js'; +import { markWinningBid } from '../../../src/adRendering.js'; let CONFIG = { accountId: '1', @@ -617,7 +617,7 @@ describe('S2S Adapter', function () { beforeEach(function () { config.resetConfig(); - config.setConfig({floors: {enabled: false}}); + config.setConfig({ floors: { enabled: false } }); adapter = new Adapter(); BID_REQUESTS = [ { @@ -705,7 +705,7 @@ describe('S2S Adapter', function () { const s2sConfig = { ...CONFIG, }; - config.setConfig({s2sConfig}); + config.setConfig({ s2sConfig }); s2sReq = { ...REQUEST, s2sConfig @@ -747,10 +747,10 @@ describe('S2S Adapter', function () { beforeEach(() => { s2sReq = { ...REQUEST, - ortb2Fragments: {global: {}}, - ad_units: REQUEST.ad_units.map(au => ({...au, ortb2Imp: {ext: {tid: 'mock-tid'}}})), + ortb2Fragments: { global: {} }, + ad_units: REQUEST.ad_units.map(au => ({ ...au, ortb2Imp: { ext: { tid: 'mock-tid' } } })), }; - BID_REQUESTS[0].bids[0].ortb2Imp = {ext: {tid: 'mock-tid'}}; + BID_REQUESTS[0].bids[0].ortb2Imp = { ext: { tid: 'mock-tid' } }; }); function makeRequest() { @@ -767,7 +767,7 @@ describe('S2S Adapter', function () { }); it('should be set to auction ID otherwise', () => { - config.setConfig({s2sConfig: CONFIG, enableTIDs: true}); + config.setConfig({ s2sConfig: CONFIG, enableTIDs: true }); const req = makeRequest(); expect(req.source.tid).to.eql(BID_REQUESTS[0].auctionId); expect(req.imp[0].ext.tid).to.eql('mock-tid'); @@ -790,7 +790,7 @@ describe('S2S Adapter', function () { } return false; }); - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); const ajax = sinon.stub(); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); sinon.assert.calledWith(ajax, sinon.match.any, sinon.match.any, sinon.match.any, sinon.match({ @@ -801,8 +801,8 @@ describe('S2S Adapter', function () { }) it('should set tmaxmax correctly when publisher has specified it', () => { - const cfg = {...CONFIG}; - config.setConfig({s2sConfig: cfg}) + const cfg = { ...CONFIG }; + config.setConfig({ s2sConfig: cfg }) // publisher has specified a tmaxmax in their setup const ortb2Fragments = { @@ -812,7 +812,7 @@ describe('S2S Adapter', function () { } } }; - const s2sCfg = {...REQUEST, cfg} + const s2sCfg = { ...REQUEST, cfg } const payloadWithFragments = { ...s2sCfg, ortb2Fragments }; adapter.callBids(payloadWithFragments, BID_REQUESTS, addBidResponse, done, ajax); @@ -822,13 +822,13 @@ describe('S2S Adapter', function () { }); it('should set tmaxmax correctly when publisher has not specified it', () => { - const cfg = {...CONFIG}; - config.setConfig({s2sConfig: cfg}) + const cfg = { ...CONFIG }; + config.setConfig({ s2sConfig: cfg }) // publisher has not specified a tmaxmax in their setup - so we should be // falling back to requestBidsTimeout const ortb2Fragments = {}; - const s2sCfg = {...REQUEST, cfg}; + const s2sCfg = { ...REQUEST, cfg }; const requestBidsTimeout = 808; const payloadWithFragments = { ...s2sCfg, ortb2Fragments, requestBidsTimeout }; @@ -844,19 +844,19 @@ describe('S2S Adapter', function () { let cfg; beforeEach(() => { - cfg = {accountId: '1', endpoint: 'mock-endpoint', maxTimeout}; - config.setConfig({s2sConfig: cfg}); + cfg = { accountId: '1', endpoint: 'mock-endpoint', maxTimeout }; + config.setConfig({ s2sConfig: cfg }); maxTimeout = maxTimeout ?? s2sDefaultConfig.maxTimeout }); it('should cap tmax to maxTimeout', () => { - adapter.callBids({...REQUEST, requestBidsTimeout: maxTimeout * 2, s2sConfig: cfg}, BID_REQUESTS, addBidResponse, done, ajax); + adapter.callBids({ ...REQUEST, requestBidsTimeout: maxTimeout * 2, s2sConfig: cfg }, BID_REQUESTS, addBidResponse, done, ajax); const req = JSON.parse(server.requests[0].requestBody); expect(req.tmax).to.eql(maxTimeout); }); it('should be set to 0.75 * requestTimeout, if lower than maxTimeout', () => { - adapter.callBids({...REQUEST, requestBidsTimeout: maxTimeout / 2}, BID_REQUESTS, addBidResponse, done, ajax); + adapter.callBids({ ...REQUEST, requestBidsTimeout: maxTimeout / 2 }, BID_REQUESTS, addBidResponse, done, ajax); const req = JSON.parse(server.requests[0].requestBody); expect(req.tmax).to.eql(Math.floor(maxTimeout / 2 * 0.75)); }) @@ -933,16 +933,16 @@ describe('S2S Adapter', function () { }); it('filters ad units without bidders when filterBidderlessCalls is true', function () { - const cfg = {...CONFIG, filterBidderlessCalls: true}; - config.setConfig({s2sConfig: cfg}); + const cfg = { ...CONFIG, filterBidderlessCalls: true }; + config.setConfig({ s2sConfig: cfg }); const badReq = utils.deepClone(REQUEST); badReq.s2sConfig = cfg; - badReq.ad_units = [{...REQUEST.ad_units[0], bids: [{bidder: null}]}]; + badReq.ad_units = [{ ...REQUEST.ad_units[0], bids: [{ bidder: null }] }]; const badBidderRequest = utils.deepClone(BID_REQUESTS); badBidderRequest[0].bidderCode = null; - badBidderRequest[0].bids = [{...badBidderRequest[0].bids[0], bidder: null}]; + badBidderRequest[0].bids = [{ ...badBidderRequest[0].bids[0], bidder: null }]; adapter.callBids(badReq, badBidderRequest, addBidResponse, done, ajax); @@ -996,8 +996,8 @@ describe('S2S Adapter', function () { }); it('should gzip payload when enabled and supported', function(done) { - const s2sCfg = Object.assign({}, CONFIG, {endpointCompression: true}); - config.setConfig({s2sConfig: s2sCfg}); + const s2sCfg = Object.assign({}, CONFIG, { endpointCompression: true }); + config.setConfig({ s2sConfig: s2sCfg }); const req = utils.deepClone(REQUEST); req.s2sConfig = s2sCfg; gzipSupportStub.returns(true); @@ -1015,8 +1015,8 @@ describe('S2S Adapter', function () { }); it('should not gzip when debug mode is enabled', function(done) { - const s2sCfg = Object.assign({}, CONFIG, {endpointCompression: true}); - config.setConfig({s2sConfig: s2sCfg}); + const s2sCfg = Object.assign({}, CONFIG, { endpointCompression: true }); + config.setConfig({ s2sConfig: s2sCfg }); const req = utils.deepClone(REQUEST); req.s2sConfig = s2sCfg; gzipSupportStub.returns(true); @@ -1036,11 +1036,11 @@ describe('S2S Adapter', function () { expect(adapter.callBids).to.exist.and.to.be.a('function'); }); - function mockTCF({applies = true, hasP1Consent = true} = {}) { + function mockTCF({ applies = true, hasP1Consent = true } = {}) { return { consentString: 'mockConsent', gdprApplies: applies, - vendorData: {purpose: {consents: {1: hasP1Consent}}}, + vendorData: { purpose: { consents: { 1: hasP1Consent } } }, } } @@ -1050,7 +1050,7 @@ describe('S2S Adapter', function () { }); it('adds gdpr consent information to ortb2 request depending on presence of module', async function () { - const consentConfig = {consentManagement: {cmpApi: 'iab'}, s2sConfig: CONFIG}; + const consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG }; config.setConfig(consentConfig); const gdprBidRequest = utils.deepClone(BID_REQUESTS); @@ -1063,7 +1063,7 @@ describe('S2S Adapter', function () { expect(requestBid.user.ext.consent).is.equal('mockConsent'); config.resetConfig(); - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(await addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); requestBid = JSON.parse(server.requests[1].requestBody); @@ -1073,7 +1073,7 @@ describe('S2S Adapter', function () { }); it('adds additional consent information to ortb2 request depending on presence of module', async function () { - const consentConfig = {consentManagement: {cmpApi: 'iab'}, s2sConfig: CONFIG}; + const consentConfig = { consentManagement: { cmpApi: 'iab' }, s2sConfig: CONFIG }; config.setConfig(consentConfig); const gdprBidRequest = utils.deepClone(BID_REQUESTS); @@ -1089,7 +1089,7 @@ describe('S2S Adapter', function () { expect(requestBid.user.ext.ConsentedProvidersSettings.consented_providers).is.equal('superduperconsent'); config.resetConfig(); - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); requestBid = JSON.parse(server.requests[1].requestBody); @@ -1105,7 +1105,7 @@ describe('S2S Adapter', function () { }); it('is added to ortb2 request when in FPD', async function () { - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); const uspBidRequest = utils.deepClone(BID_REQUESTS); uspBidRequest[0].uspConsent = '1NYN'; @@ -1116,7 +1116,7 @@ describe('S2S Adapter', function () { expect(requestBid.regs.ext.us_privacy).is.equal('1NYN'); config.resetConfig(); - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(await addFpdEnrichmentsToS2SRequest(REQUEST, BID_REQUESTS), BID_REQUESTS, addBidResponse, done, ajax); requestBid = JSON.parse(server.requests[1].requestBody); @@ -1131,7 +1131,7 @@ describe('S2S Adapter', function () { }); it('is added to ortb2 request when in bidRequest', async function () { - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); const consentBidRequest = utils.deepClone(BID_REQUESTS); consentBidRequest[0].uspConsent = '1NYN'; @@ -1145,7 +1145,7 @@ describe('S2S Adapter', function () { expect(requestBid.user.ext.consent).is.equal('mockConsent'); config.resetConfig(); - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); requestBid = JSON.parse(server.requests[1].requestBody); @@ -1186,8 +1186,8 @@ describe('S2S Adapter', function () { ...REQUEST, ortb2Fragments: { global: { - device: {ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC'}, - app: {bundle: 'com.test.app'}, + device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, + app: { bundle: 'com.test.app' }, } } }, BID_REQUESTS) @@ -1200,7 +1200,7 @@ describe('S2S Adapter', function () { }) sinon.assert.match(requestBid.app, { bundle: 'com.test.app', - publisher: {'id': '1'} + publisher: { 'id': '1' } }); }); @@ -1218,8 +1218,8 @@ describe('S2S Adapter', function () { ...REQUEST, ortb2Fragments: { global: { - device: {ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC'}, - app: {bundle: 'com.test.app'}, + device: { ifa: '6D92078A-8246-4BA4-AE5B-76104861E7DC' }, + app: { bundle: 'com.test.app' }, } } }, BID_REQUESTS) @@ -1232,7 +1232,7 @@ describe('S2S Adapter', function () { }) sinon.assert.match(requestBid.app, { bundle: 'com.test.app', - publisher: {'id': '1'} + publisher: { 'id': '1' } }); }); @@ -1370,16 +1370,16 @@ describe('S2S Adapter', function () { code: 'au1', transactionId: 't1', mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } }, - bids: [{bidder: 'b1', bid_id: 1}] + bids: [{ bidder: 'b1', bid_id: 1 }] }, { code: 'au2', transactionId: 't2', - bids: [{bidder: 'b2', bid_id: 2}], + bids: [{ bidder: 'b2', bid_id: 2 }], mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } } } ]; @@ -1454,12 +1454,12 @@ describe('S2S Adapter', function () { code: 'au1', transactionId: 't1', mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } }, bids: [ - {bidder: 'b2', bid_id: 2}, - {bidder: 'b3', bid_id: 3}, - {bidder: 'b1', bid_id: 1}, + { bidder: 'b2', bid_id: 2 }, + { bidder: 'b3', bid_id: 3 }, + { bidder: 'b1', bid_id: 1 }, ] } ] @@ -1487,13 +1487,13 @@ describe('S2S Adapter', function () { }, 'mediaType level floors': { target: 'imp.0.banner.ext', - floorFilter: ({mediaType, size}) => size === '*' && mediaType !== '*' + floorFilter: ({ mediaType, size }) => size === '*' && mediaType !== '*' }, 'format level floors': { target: 'imp.0.banner.format.0.ext', - floorFilter: ({size}) => size !== '*' + floorFilter: ({ size }) => size !== '*' } - }).forEach(([t, {target, floorFilter}]) => { + }).forEach(([t, { target, floorFilter }]) => { describe(t, () => { beforeEach(() => { if (floorFilter != null) { @@ -1534,7 +1534,7 @@ describe('S2S Adapter', function () { throw new Error(); } } - }).forEach(([t, {expectDesc, expectedFloor, expectedCur, conversionFn}]) => { + }).forEach(([t, { expectDesc, expectedFloor, expectedCur, conversionFn }]) => { describe(`and currency conversion ${t}`, () => { let mockConvertCurrency; const origConvertCurrency = getGlobal().convertCurrency; @@ -1631,7 +1631,7 @@ describe('S2S Adapter', function () { }; config.setConfig(_config); - adapter.callBids({...REQUEST, s2sConfig: Object.assign({}, CONFIG, s2sDefaultConfig)}, BID_REQUESTS, addBidResponse, done, ajax); + adapter.callBids({ ...REQUEST, s2sConfig: Object.assign({}, CONFIG, s2sDefaultConfig) }, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); const ortbReq = JSON.parse(requestBid.imp[0].native.request); expect(ortbReq).to.deep.equal({ @@ -1669,27 +1669,27 @@ describe('S2S Adapter', function () { ...CONFIG, ortbNative: { eventtrackers: [ - {event: 1, methods: [1, 2]} + { event: 1, methods: [1, 2] } ] } } config.setConfig({ s2sConfig: cfg }); - adapter.callBids({...REQUEST, s2sConfig: cfg}, BID_REQUESTS, addBidResponse, done, ajax); + adapter.callBids({ ...REQUEST, s2sConfig: cfg }, BID_REQUESTS, addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); const ortbReq = JSON.parse(requestBid.imp[0].native.request); expect(ortbReq).to.eql({ ...ORTB_NATIVE_REQ, eventtrackers: [ - {event: 1, methods: [1, 2]} + { event: 1, methods: [1, 2] } ] }) }) it('should not include ext.aspectratios if adunit\'s aspect_ratios do not define radio_width and ratio_height', () => { const req = deepClone(REQUEST); - req.ad_units[0].mediaTypes.native.icon.aspect_ratios[0] = {'min_width': 1, 'min_height': 2}; + req.ad_units[0].mediaTypes.native.icon.aspect_ratios[0] = { 'min_width': 1, 'min_height': 2 }; prepRequest(req); adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax); const nativeReq = JSON.parse(JSON.parse(server.requests[0].requestBody).imp[0].native.request); @@ -1757,7 +1757,7 @@ describe('S2S Adapter', function () { ...REQUEST, ortb2Fragments: { global: { - app: {bundle: 'com.test.app'}, + app: { bundle: 'com.test.app' }, site: { publisher: { id: '1234', @@ -1788,7 +1788,7 @@ describe('S2S Adapter', function () { const request = utils.deepClone(REQUEST); request.ad_units[0].bids = [aliasBidder]; - adapter.callBids(request, [{...BID_REQUESTS[0], bidderCode: 'beintoo'}], addBidResponse, done, ajax); + adapter.callBids(request, [{ ...BID_REQUESTS[0], bidderCode: 'beintoo' }], addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.ext).to.haveOwnProperty('prebid'); @@ -1823,7 +1823,7 @@ describe('S2S Adapter', function () { request.ad_units[0].bids = [aliasBidder]; request.s2sConfig = adjustedConfig; - adapter.callBids(request, [{...BID_REQUESTS[0], bidderCode: aliasBidder.bidder}], addBidResponse, done, ajax); + adapter.callBids(request, [{ ...BID_REQUESTS[0], bidderCode: aliasBidder.bidder }], addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.ext.prebid.aliases).to.deep.equal({ bidderD: 'mockBidder' }); @@ -1844,7 +1844,7 @@ describe('S2S Adapter', function () { // TODO: stub this getGlobal().aliasBidder('appnexus', alias); - adapter.callBids(request, [{...BID_REQUESTS[0], bidderCode: 'foobar'}], addBidResponse, done, ajax); + adapter.callBids(request, [{ ...BID_REQUESTS[0], bidderCode: 'foobar' }], addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); expect(requestBid.ext).to.haveOwnProperty('prebid'); @@ -1883,7 +1883,7 @@ describe('S2S Adapter', function () { const request = utils.deepClone(REQUEST); request.ad_units[0].bids = [aliasBidder]; - adapter.callBids(request, [{...BID_REQUESTS[0], bidderCode: aliasBidder.bidder}], addBidResponse, done, ajax); + adapter.callBids(request, [{ ...BID_REQUESTS[0], bidderCode: aliasBidder.bidder }], addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); @@ -1920,7 +1920,7 @@ describe('S2S Adapter', function () { // TODO: stub this getGlobal().aliasBidder('appnexus', alias, { skipPbsAliasing: true }); - adapter.callBids(request, [{...BID_REQUESTS[0], bidderCode: aliasBidder.bidder}], addBidResponse, done, ajax); + adapter.callBids(request, [{ ...BID_REQUESTS[0], bidderCode: aliasBidder.bidder }], addBidResponse, done, ajax); const requestBid = JSON.parse(server.requests[0].requestBody); @@ -2087,7 +2087,7 @@ describe('S2S Adapter', function () { }); it('when gdprApplies is false', () => { - bidderReqs[0].gdprConsent = mockTCF({applies: false}); + bidderReqs[0].gdprConsent = mockTCF({ applies: false }); const req = callCookieSync(); expect(req.gdpr).is.equal(0); expect(req.gdpr_consent).is.undefined; @@ -2162,7 +2162,7 @@ describe('S2S Adapter', function () { site: { domain: 'nytimes.com', page: 'http://www.nytimes.com', - publisher: {id: '2'} + publisher: { id: '2' } }, device, } @@ -2211,7 +2211,7 @@ describe('S2S Adapter', function () { ...CONFIG, bidders: ['appnexus', 'rubicon'] } - config.setConfig({s2sConfig}); + config.setConfig({ s2sConfig }); req = { ...REQUEST, s2sConfig, @@ -2219,7 +2219,7 @@ describe('S2S Adapter', function () { global: { user: { ext: { - eids: [{source: 'idA', id: 1}, {source: 'idB', id: 2}] + eids: [{ source: 'idA', id: 1 }, { source: 'idB', id: 2 }] } } }, @@ -2227,7 +2227,7 @@ describe('S2S Adapter', function () { appnexus: { user: { ext: { - eids: [{source: 'idC', id: 3}] + eids: [{ source: 'idC', id: 3 }] } } } @@ -2239,9 +2239,9 @@ describe('S2S Adapter', function () { adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax); const payload = JSON.parse(server.requests[0].requestBody); expect(payload.user.ext.eids).to.eql([ - {source: 'idA', id: 1}, - {source: 'idB', id: 2}, - {source: 'idC', id: 3} + { source: 'idA', id: 1 }, + { source: 'idB', id: 2 }, + { source: 'idC', id: 3 } ]); expect(payload.ext.prebid.data.eidpermissions).to.eql([{ bidders: ['appnexus'], @@ -2252,7 +2252,7 @@ describe('S2S Adapter', function () { it('should not set eidpermissions for unrequested bidders', () => { req.ortb2Fragments.bidder.unknown = { user: { - eids: [{source: 'idC', id: 3}, {source: 'idD', id: 4}] + eids: [{ source: 'idC', id: 3 }, { source: 'idD', id: 4 }] } } adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax); @@ -2278,15 +2278,15 @@ describe('S2S Adapter', function () { req.ortb2Fragments.bidder.rubicon = { user: { ext: { - eids: [{source: 'idC', id: 4}] + eids: [{ source: 'idC', id: 4 }] } } } adapter.callBids(req, BID_REQUESTS, addBidResponse, done, ajax); const payload = JSON.parse(server.requests[0].requestBody); const globalEids = [ - {source: 'idA', id: 1}, - {source: 'idB', id: 2}, + { source: 'idA', id: 1 }, + { source: 'idB', id: 2 }, ] expect(payload.user.ext.eids).to.eql(globalEids); expect(payload.ext.prebid?.data?.eidpermissions).to.not.exist; @@ -2295,7 +2295,7 @@ describe('S2S Adapter', function () { bidders: ['appnexus'], config: { ortb2: { - user: {ext: {eids: globalEids.concat([{source: 'idC', id: 3}])}} + user: { ext: { eids: globalEids.concat([{ source: 'idC', id: 3 }]) } } } } }, @@ -2303,7 +2303,7 @@ describe('S2S Adapter', function () { bidders: ['rubicon'], config: { ortb2: { - user: {ext: {eids: globalEids.concat([{source: 'idC', id: 4}])}} + user: { ext: { eids: globalEids.concat([{ source: 'idC', id: 4 }]) } } } } } @@ -2658,22 +2658,22 @@ describe('S2S Adapter', function () { Object.entries({ 'set': {}, - 'override': {source: {ext: {schain: 'pub-provided'}}} + 'override': { source: { ext: { schain: 'pub-provided' } } } }).forEach(([t, fpd]) => { it(`should not ${t} source.ext.schain`, () => { const bidderReqs = [ - {...deepClone(BID_REQUESTS[0]), bidderCode: 'A'}, - {...deepClone(BID_REQUESTS[0]), bidderCode: 'B'}, - {...deepClone(BID_REQUESTS[0]), bidderCode: 'C'} + { ...deepClone(BID_REQUESTS[0]), bidderCode: 'A' }, + { ...deepClone(BID_REQUESTS[0]), bidderCode: 'B' }, + { ...deepClone(BID_REQUESTS[0]), bidderCode: 'C' } ]; - const chain1 = {chain: 1}; - const chain2 = {chain: 2}; + const chain1 = { chain: 1 }; + const chain2 = { chain: 2 }; bidderReqs[0].bids[0].schain = chain1; bidderReqs[1].bids[0].schain = chain2; bidderReqs[2].bids[0].schain = chain2; - adapter.callBids({...REQUEST, ortb2Fragments: {global: fpd}}, bidderReqs, addBidResponse, done, ajax); + adapter.callBids({ ...REQUEST, ortb2Fragments: { global: fpd } }, bidderReqs, addBidResponse, done, ajax); const req = JSON.parse(server.requests[0].requestBody); expect(req.source?.ext?.schain).to.eql(fpd?.source?.ext?.schain); }) @@ -2760,7 +2760,7 @@ describe('S2S Adapter', function () { }; const site = { - content: {userrating: 4}, + content: { userrating: 4 }, ext: { data: { pageType: 'article', @@ -2770,7 +2770,7 @@ describe('S2S Adapter', function () { }; const user = { yob: '1984', - geo: {country: 'ca'}, + geo: { country: 'ca' }, ext: { data: { registered: true, @@ -2787,7 +2787,7 @@ describe('S2S Adapter', function () { config: { ortb2: { site: { - content: {userrating: 4}, + content: { userrating: 4 }, ext: { data: { pageType: 'article', @@ -2797,7 +2797,7 @@ describe('S2S Adapter', function () { }, user: { yob: '1984', - geo: {country: 'ca'}, + geo: { country: 'ca' }, ext: { data: { registered: true, @@ -2820,8 +2820,8 @@ describe('S2S Adapter', function () { }, commonSite); const ortb2Fragments = { - global: {site: commonSite, user: commonUser, badv, bcat}, - bidder: Object.fromEntries(allowedBidders.map(bidder => [bidder, {site, user, bcat, badv}])) + global: { site: commonSite, user: commonUser, badv, bcat }, + bidder: Object.fromEntries(allowedBidders.map(bidder => [bidder, { site, user, bcat, badv }])) }; adapter.callBids(await addFpdEnrichmentsToS2SRequest({ @@ -2837,10 +2837,10 @@ describe('S2S Adapter', function () { }); it('passes first party data in request for unknown when allowUnknownBidderCodes is true', async () => { - const cfg = {...CONFIG, allowUnknownBidderCodes: true}; - config.setConfig({s2sConfig: cfg}); + const cfg = { ...CONFIG, allowUnknownBidderCodes: true }; + config.setConfig({ s2sConfig: cfg }); - const clonedReq = {...REQUEST, s2sConfig: cfg} + const clonedReq = { ...REQUEST, s2sConfig: cfg } const s2sBidRequest = utils.deepClone(clonedReq); const bidRequests = utils.deepClone(BID_REQUESTS); @@ -2854,7 +2854,7 @@ describe('S2S Adapter', function () { }; const site = { - content: {userrating: 4}, + content: { userrating: 4 }, ext: { data: { pageType: 'article', @@ -2864,7 +2864,7 @@ describe('S2S Adapter', function () { }; const user = { yob: '1984', - geo: {country: 'ca'}, + geo: { country: 'ca' }, ext: { data: { registered: true, @@ -2881,7 +2881,7 @@ describe('S2S Adapter', function () { config: { ortb2: { site: { - content: {userrating: 4}, + content: { userrating: 4 }, ext: { data: { pageType: 'article', @@ -2891,7 +2891,7 @@ describe('S2S Adapter', function () { }, user: { yob: '1984', - geo: {country: 'ca'}, + geo: { country: 'ca' }, ext: { data: { registered: true, @@ -2914,8 +2914,8 @@ describe('S2S Adapter', function () { }, commonSite); const ortb2Fragments = { - global: {site: commonSite, user: commonUser, badv, bcat}, - bidder: Object.fromEntries(allowedBidders.map(bidder => [bidder, {site, user, bcat, badv}])) + global: { site: commonSite, user: commonUser, badv, bcat }, + bidder: Object.fromEntries(allowedBidders.map(bidder => [bidder, { site, user, bcat, badv }])) }; // adapter.callBids({ ...REQUEST, s2sConfig: cfg }, BID_REQUESTS, addBidResponse, done, ajax); @@ -3023,7 +3023,7 @@ describe('S2S Adapter', function () { }) it('should be set on imp.ext.prebid.imp', () => { const s2sReq = utils.deepClone(REQUEST); - s2sReq.ad_units[0].ortb2Imp = {l0: 'adUnit'}; + s2sReq.ad_units[0].ortb2Imp = { l0: 'adUnit' }; s2sReq.ad_units[0].bids = [ { bidder: 'A', @@ -3062,8 +3062,8 @@ describe('S2S Adapter', function () { const req = JSON.parse(server.requests[0].requestBody); expect(req.imp[0].l0).to.eql('adUnit'); expect(req.imp[0].ext.prebid.imp).to.eql({ - A: {l2: 'A'}, - B: {l2: 'B'} + A: { l2: 'A' }, + B: { l2: 'B' } }); }); }); @@ -3122,7 +3122,7 @@ describe('S2S Adapter', function () { let success, error; beforeEach(() => { const mockAjax = function (_, callback) { - ({success, error} = callback); + ({ success, error } = callback); } config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, mockAjax); @@ -3138,7 +3138,7 @@ describe('S2S Adapter', function () { 'other errors': false }).forEach(([t, timedOut]) => { it(`passing timedOut = ${timedOut} on ${t}`, () => { - error('', {timedOut}); + error('', { timedOut }); sinon.assert.calledWith(done, timedOut); }) }) @@ -3316,12 +3316,12 @@ describe('S2S Adapter', function () { it('handles seatnonbid responses and emits SEAT_NON_BID', function () { const original = CONFIG; CONFIG.extPrebid = { returnallbidstatus: true }; - const nonbidResponse = {...RESPONSE_OPENRTB, ext: {seatnonbid: [{}]}}; + const nonbidResponse = { ...RESPONSE_OPENRTB, ext: { seatnonbid: [{}] } }; config.setConfig({ CONFIG }); CONFIG = original; adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); const responding = deepClone(nonbidResponse); - Object.assign(responding.ext.seatnonbid, [{auctionId: 2}]) + Object.assign(responding.ext.seatnonbid, [{ auctionId: 2 }]) server.requests[0].respond(200, {}, JSON.stringify(responding)); const event = events.emit.thirdCall.args; expect(event[0]).to.equal(EVENTS.SEAT_NON_BID); @@ -3333,12 +3333,12 @@ describe('S2S Adapter', function () { it('emits the PBS_ANALYTICS event and captures seatnonbid responses', function () { const original = CONFIG; CONFIG.extPrebid = { returnallbidstatus: true }; - const nonbidResponse = {...RESPONSE_OPENRTB, ext: {seatnonbid: [{}]}}; + const nonbidResponse = { ...RESPONSE_OPENRTB, ext: { seatnonbid: [{}] } }; config.setConfig({ CONFIG }); CONFIG = original; adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); const responding = deepClone(nonbidResponse); - Object.assign(responding.ext.seatnonbid, [{auctionId: 2}]) + Object.assign(responding.ext.seatnonbid, [{ auctionId: 2 }]) server.requests[0].respond(200, {}, JSON.stringify(responding)); const event = events.emit.getCall(3).args; expect(event[0]).to.equal(EVENTS.PBS_ANALYTICS); @@ -3350,7 +3350,7 @@ describe('S2S Adapter', function () { it('emits the PBS_ANALYTICS event and captures atag responses', function () { const original = CONFIG; CONFIG.extPrebid = { returnallbidstatus: true }; - const atagResponse = {...RESPONSE_OPENRTB, ext: {prebid: {analytics: {tags: ['data']}}}}; + const atagResponse = { ...RESPONSE_OPENRTB, ext: { prebid: { analytics: { tags: ['data'] } } } }; config.setConfig({ CONFIG }); CONFIG = original; adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); @@ -3574,13 +3574,13 @@ describe('S2S Adapter', function () { if (FEATURES.NATIVE) { it('handles OpenRTB native responses', function () { const stub = sinon.stub(auctionManager, 'index'); - stub.get(() => stubAuctionIndex({adUnits: REQUEST.ad_units})); + stub.get(() => stubAuctionIndex({ adUnits: REQUEST.ad_units })); const s2sConfig = Object.assign({}, CONFIG, { endpoint: { p1Consent: 'https://prebidserverurl/openrtb2/auction?querystring=param' } }); - config.setConfig({s2sConfig}); + config.setConfig({ s2sConfig }); const s2sBidRequest = utils.deepClone(REQUEST); s2sBidRequest.s2sConfig = s2sConfig; @@ -3604,7 +3604,7 @@ describe('S2S Adapter', function () { config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(REQUEST, BID_REQUESTS, addBidResponse, done, ajax); const response = deepClone(RESPONSE_OPENRTB); - Object.assign(response.seatbid[0].bid[0], {w: null, h: null}); + Object.assign(response.seatbid[0].bid[0], { w: null, h: null }); server.requests[0].respond(200, {}, JSON.stringify(response)); expect(addBidResponse.reject.calledOnce).to.be.true; expect(addBidResponse.called).to.be.false; @@ -3636,25 +3636,25 @@ describe('S2S Adapter', function () { let bidReq, response; function mks2sReq(s2sConfig = CONFIG) { - return {...REQUEST, s2sConfig, ad_units: [{...REQUEST.ad_units[0], bids: [{bidder: null, bid_id: 'testId'}]}]}; + return { ...REQUEST, s2sConfig, ad_units: [{ ...REQUEST.ad_units[0], bids: [{ bidder: null, bid_id: 'testId' }] }] }; } beforeEach(() => { - bidReq = {...BID_REQUESTS[0], bidderCode: null, bids: [{...BID_REQUESTS[0].bids[0], bidder: null, bidId: 'testId'}]} + bidReq = { ...BID_REQUESTS[0], bidderCode: null, bids: [{ ...BID_REQUESTS[0].bids[0], bidder: null, bidId: 'testId' }] } response = deepClone(RESPONSE_OPENRTB); response.seatbid[0].seat = 'storedImpression'; }) it('uses "null" request\'s ID for all responses, when a null request is present', function () { - const cfg = {...CONFIG, allowUnknownBidderCodes: true}; - config.setConfig({s2sConfig: cfg}); + const cfg = { ...CONFIG, allowUnknownBidderCodes: true }; + config.setConfig({ s2sConfig: cfg }); adapter.callBids(mks2sReq(cfg), [bidReq], addBidResponse, done, ajax); server.requests[0].respond(200, {}, JSON.stringify(response)); - sinon.assert.calledWith(addBidResponse, sinon.match.any, sinon.match({bidderCode: 'storedImpression', requestId: 'testId'})) + sinon.assert.calledWith(addBidResponse, sinon.match.any, sinon.match({ bidderCode: 'storedImpression', requestId: 'testId' })) }); it('does not allow null requests (= stored impressions) if allowUnknownBidderCodes is not set', () => { - config.setConfig({s2sConfig: CONFIG}); + config.setConfig({ s2sConfig: CONFIG }); adapter.callBids(mks2sReq(), [bidReq], addBidResponse, done, ajax); server.requests[0].respond(200, {}, JSON.stringify(response)); expect(addBidResponse.called).to.be.false; @@ -3663,11 +3663,11 @@ describe('S2S Adapter', function () { }) it('copies ortb2Imp to response when there is only a null bid', () => { - const cfg = {...CONFIG}; - config.setConfig({s2sConfig: cfg}); - const ortb2Imp = {ext: {prebid: {storedrequest: 'value'}}}; - const req = {...REQUEST, s2sConfig: cfg, ad_units: [{...REQUEST.ad_units[0], bids: [{bidder: null, bid_id: 'testId'}], ortb2Imp}]}; - const bidReq = {...BID_REQUESTS[0], bidderCode: null, bids: [{...BID_REQUESTS[0].bids[0], bidder: null, bidId: 'testId'}]} + const cfg = { ...CONFIG }; + config.setConfig({ s2sConfig: cfg }); + const ortb2Imp = { ext: { prebid: { storedrequest: 'value' } } }; + const req = { ...REQUEST, s2sConfig: cfg, ad_units: [{ ...REQUEST.ad_units[0], bids: [{ bidder: null, bid_id: 'testId' }], ortb2Imp }] }; + const bidReq = { ...BID_REQUESTS[0], bidderCode: null, bids: [{ ...BID_REQUESTS[0].bids[0], bidder: null, bidId: 'testId' }] } adapter.callBids(req, [bidReq], addBidResponse, done, ajax); const actual = JSON.parse(server.requests[0].requestBody); sinon.assert.match(actual.imp[0], sinon.match(ortb2Imp)); @@ -3772,7 +3772,7 @@ describe('S2S Adapter', function () { }); after(() => { - addPaapiConfig.getHooks({hook: fledgeHook}).remove(); + addPaapiConfig.getHooks({ hook: fledgeHook }).remove(); }) beforeEach(function () { @@ -3804,8 +3804,8 @@ describe('S2S Adapter', function () { function expectFledgeCalls() { const auctionId = bidderRequests[0].auctionId; - sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: bidderRequests[0].ortb2, ortb2Imp: bidderRequests[0].bids[0].ortb2Imp}), sinon.match({config: {id: 1}})) - sinon.assert.calledWith(fledgeStub, sinon.match({auctionId, adUnitCode: AU, ortb2: undefined, ortb2Imp: undefined}), sinon.match({config: {id: 2}})) + sinon.assert.calledWith(fledgeStub, sinon.match({ auctionId, adUnitCode: AU, ortb2: bidderRequests[0].ortb2, ortb2Imp: bidderRequests[0].bids[0].ortb2Imp }), sinon.match({ config: { id: 1 } })) + sinon.assert.calledWith(fledgeStub, sinon.match({ auctionId, adUnitCode: AU, ortb2: undefined, ortb2Imp: undefined }), sinon.match({ config: { id: 2 } })) } it('calls addPaapiConfig alongside addBidResponse', function () { @@ -3824,7 +3824,7 @@ describe('S2S Adapter', function () { it('wraps call in runWithBidder', () => { let fail = false; - fledgeStub.callsFake(({bidder}) => { + fledgeStub.callsFake(({ bidder }) => { try { expect(bidder).to.exist.and.to.eql(config.getCurrentBidder()); } catch (e) { @@ -3878,9 +3878,9 @@ describe('S2S Adapter', function () { }); it('should translate wurl and burl into eventtrackers', () => { - const burlEvent = {event: 1, method: 1, url: 'burl'}; - const winEvent = {event: 500, method: 1, url: 'events.win'}; - const trackerEvent = {event: 500, method: 1, url: 'eventtracker'}; + const burlEvent = { event: 1, method: 1, url: 'burl' }; + const winEvent = { event: 500, method: 1, url: 'events.win' }; + const trackerEvent = { event: 500, method: 1, url: 'eventtracker' }; const resp = utils.deepClone(RESPONSE_OPENRTB); resp.seatbid[0].bid[0].ext.eventtrackers = [ @@ -4039,7 +4039,7 @@ describe('S2S Adapter', function () { // Add syncEndpoint so that the request goes to the User Sync endpoint // Modify the bidders property to include an alias for Rubicon adapter - s2sConfig.syncEndpoint = {p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync'}; + s2sConfig.syncEndpoint = { p1Consent: 'https://prebid.adnxs.com/pbs/v1/cookie_sync' }; s2sConfig.bidders = ['appnexus', 'rubicon-alias']; setupAlias(s2sConfig); @@ -4177,7 +4177,7 @@ describe('S2S Adapter', function () { expect(requestBid.ext.prebid.floors).to.be.undefined; - config.setConfig({floors: {}}); + config.setConfig({ floors: {} }); adapter.callBids(REQUEST, bidRequest, addBidResponse, done, ajax); requestBid = JSON.parse(server.requests[1].requestBody); @@ -4239,16 +4239,16 @@ describe('S2S Adapter', function () { code: 'au1', transactionId: 't1', mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } }, - bids: [{bidder: 'b1', bid_id: 1}] + bids: [{ bidder: 'b1', bid_id: 1 }] }, { code: 'au2', transactionId: 't2', - bids: [{bidder: 'b2', bid_id: 2}], + bids: [{ bidder: 'b2', bid_id: 2 }], mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } } } ]; @@ -4313,16 +4313,16 @@ describe('S2S Adapter', function () { code: 'au1', transactionId: 't1', mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } }, - bids: [{bidder: 'b1', bid_id: 1}] + bids: [{ bidder: 'b1', bid_id: 1 }] }, { code: 'au2', transactionId: 't2', - bids: [{bidder: 'b2', bid_id: 2}], + bids: [{ bidder: 'b2', bid_id: 2 }], mediaTypes: { - banner: {sizes: [1, 1]} + banner: { sizes: [1, 1] } }, ortb2Imp: { ext: { @@ -4380,12 +4380,12 @@ describe('S2S Adapter', function () { }, bidder: { bidderA: { - k1: {k3: 'val'} + k1: { k3: 'val' } } }, expected: { bidderA: { - k1: {k3: 'val'} + k1: { k3: 'val' } } } }, @@ -4396,19 +4396,19 @@ describe('S2S Adapter', function () { }, bidder: { bidderA: { - k: {inner: 'val'} + k: { inner: 'val' } } }, expected: { bidderA: { - k: {inner: 'val'} + k: { inner: 'val' } } } }, { t: 'uses bidder config on type mismatch (object/array)', global: { - k: {inner: 'val'} + k: { inner: 'val' } }, bidder: { bidderA: { @@ -4495,32 +4495,32 @@ describe('S2S Adapter', function () { { t: 'does not repeat equal elements', global: { - array: [{id: 1}] + array: [{ id: 1 }] }, bidder: { bidderA: { - array: [{id: 1}, {id: 2}] + array: [{ id: 1 }, { id: 2 }] } }, expected: { bidderA: { - array: [{id: 1}, {id: 2}] + array: [{ id: 1 }, { id: 2 }] } } } - ].forEach(({t, global, bidder, expected}) => { + ].forEach(({ t, global, bidder, expected }) => { it(t, () => { - expect(getPBSBidderConfig({global, bidder})).to.eql(expected); + expect(getPBSBidderConfig({ global, bidder })).to.eql(expected); }) }) }); describe('EID handling', () => { function mkEid(source, value = source) { - return {source, value}; + return { source, value }; } function eidEntry(source, value = source, bidders = false) { - return {eid: {source, value}, bidders}; + return { eid: { source, value }, bidders }; } describe('extractEids', () => { @@ -4622,9 +4622,9 @@ describe('S2S Adapter', function () { ] } } - ].forEach(({t, global = {}, bidder = {}, expected}) => { + ].forEach(({ t, global = {}, bidder = {}, expected }) => { it(t, () => { - const {eids, conflicts} = extractEids({global, bidder}); + const { eids, conflicts } = extractEids({ global, bidder }); expect(eids).to.have.deep.members(expected.eids); expect(Array.from(conflicts)).to.have.members(expected.conflicts || []); }) @@ -4660,7 +4660,7 @@ describe('S2S Adapter', function () { ] })).to.eql({ global: [mkEid('idA'), mkEid('idB')], - permissions: [{source: 'idB', bidders: ['bidderB']}], + permissions: [{ source: 'idB', bidders: ['bidderB'] }], bidder: {} }) }) @@ -4706,7 +4706,7 @@ describe('S2S Adapter', function () { conflicts: new Set(['idA']) })).to.eql({ global: [mkEid('idA', 'idA1'), mkEid('idB')], - permissions: [{source: 'idB', bidders: ['bidderB']}], + permissions: [{ source: 'idB', bidders: ['bidderB'] }], bidder: { bidderA: [mkEid('idA', 'idA2')] } diff --git a/test/spec/modules/previousAuctionInfo_spec.js b/test/spec/modules/previousAuctionInfo_spec.js index 762ba5d10ef..c352ccca9e1 100644 --- a/test/spec/modules/previousAuctionInfo_spec.js +++ b/test/spec/modules/previousAuctionInfo_spec.js @@ -3,7 +3,7 @@ import sinon from 'sinon'; import { expect } from 'chai'; import { config } from 'src/config.js'; import * as events from 'src/events.js'; -import {CONFIG_NS, resetPreviousAuctionInfo, startAuctionHook} from '../../../modules/previousAuctionInfo/index.js'; +import { CONFIG_NS, resetPreviousAuctionInfo, startAuctionHook } from '../../../modules/previousAuctionInfo/index.js'; import { REJECTION_REASON } from '../../../src/constants.js'; describe('previous auction info', () => { @@ -177,7 +177,7 @@ describe('previous auction info', () => { next = sinon.spy(); }); function runHook() { - startAuctionHook(next, {ortb2Fragments: {global, bidder}}); + startAuctionHook(next, { ortb2Fragments: { global, bidder } }); } it('should not add info when none is available', () => { runHook(); @@ -191,8 +191,8 @@ describe('previous auction info', () => { describe('when info is available', () => { beforeEach(() => { Object.assign(previousAuctionInfo.auctionState, { - bidder1: [{transactionId: 'tid1', auction: '1'}], - bidder2: [{transactionId: 'tid2', auction: '2'}] + bidder1: [{ transactionId: 'tid1', auction: '1' }], + bidder2: [{ transactionId: 'tid2', auction: '2' }] }) }) @@ -204,19 +204,19 @@ describe('previous auction info', () => { } it('should set info for enabled bidders, when only some are enabled', () => { - config.setConfig({[CONFIG_NS]: {enabled: true, bidders: ['bidder1']}}); + config.setConfig({ [CONFIG_NS]: { enabled: true, bidders: ['bidder1'] } }); runHook(); expect(extractInfo()).to.eql({ - bidder1: [{auction: '1'}] + bidder1: [{ auction: '1' }] }) }); it('should set info for all bidders, when none is specified', () => { - config.setConfig({[CONFIG_NS]: {enabled: true}}); + config.setConfig({ [CONFIG_NS]: { enabled: true } }); runHook(); expect(extractInfo()).to.eql({ - bidder1: [{auction: '1'}], - bidder2: [{auction: '2'}] + bidder1: [{ auction: '1' }], + bidder2: [{ auction: '2' }] }) }) }) diff --git a/test/spec/modules/priceFloors_spec.js b/test/spec/modules/priceFloors_spec.js index 761e5256674..746c8afd667 100644 --- a/test/spec/modules/priceFloors_spec.js +++ b/test/spec/modules/priceFloors_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import * as utils from 'src/utils.js'; import { getGlobal } from 'src/prebidGlobal.js'; import { EVENTS } from 'src/constants.js'; @@ -19,12 +19,12 @@ import { import * as events from 'src/events.js'; import * as mockGpt from '../integration/faker/googletag.js'; import 'src/prebid.js'; -import {createBid} from '../../../src/bidfactory.js'; -import {auctionManager} from '../../../src/auctionManager.js'; -import {stubAuctionIndex} from '../../helpers/indexStub.js'; -import {guardTids} from '../../../src/adapters/bidderFactory.js'; +import { createBid } from '../../../src/bidfactory.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { stubAuctionIndex } from '../../helpers/indexStub.js'; +import { guardTids } from '../../../src/adapters/bidderFactory.js'; import * as activities from '../../../src/activities/rules.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; describe('the price floors module', function () { let logErrorSpy; @@ -82,6 +82,7 @@ describe('the price floors module', function () { endpoint: {}, enforcement: { enforceJS: true, + enforceBidders: ['*'], enforcePBS: false, floorDeals: false, bidAdjustment: true @@ -95,6 +96,7 @@ describe('the price floors module', function () { endpoint: {}, enforcement: { enforceJS: true, + enforceBidders: ['*'], enforcePBS: false, floorDeals: false, bidAdjustment: true @@ -108,6 +110,7 @@ describe('the price floors module', function () { endpoint: {}, enforcement: { enforceJS: true, + enforceBidders: ['*'], enforcePBS: false, floorDeals: false, bidAdjustment: true @@ -125,8 +128,8 @@ describe('the price floors module', function () { function getAdUnitMock(code = 'adUnit-code') { return { code, - mediaTypes: {banner: { sizes: [[300, 200], [300, 600]] }, native: {}}, - bids: [{bidder: 'someBidder', adUnitCode: code}, {bidder: 'someOtherBidder', adUnitCode: code}] + mediaTypes: { banner: { sizes: [[300, 200], [300, 600]] }, native: {} }, + bids: [{ bidder: 'someBidder', adUnitCode: code }, { bidder: 'someOtherBidder', adUnitCode: code }] }; } beforeEach(function() { @@ -138,7 +141,7 @@ describe('the price floors module', function () { afterEach(function() { clock.restore(); - handleSetFloorsConfig({enabled: false}); + handleSetFloorsConfig({ enabled: false }); sandbox.restore(); utils.logError.restore(); utils.logWarn.restore(); @@ -320,7 +323,7 @@ describe('the price floors module', function () { default: 0.5 }); - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'banner', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 0, matchingFloor: 0, @@ -328,7 +331,7 @@ describe('the price floors module', function () { matchingRule: 'test_div_1' }); - expect(getFirstMatchingFloor(inputFloorData, {...basicBidRequest, adUnitCode: 'test_div_2'}, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, { ...basicBidRequest, adUnitCode: 'test_div_2' }, { mediaType: 'banner', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 2, matchingFloor: 2, @@ -336,7 +339,7 @@ describe('the price floors module', function () { matchingRule: 'test_div_2' }); - expect(getFirstMatchingFloor(inputFloorData, {...basicBidRequest, adUnitCode: 'test_div_3'}, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, { ...basicBidRequest, adUnitCode: 'test_div_3' }, { mediaType: 'banner', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 0.5, matchingFloor: 0.5, @@ -396,7 +399,7 @@ describe('the price floors module', function () { }); it('selects the right floor for different mediaTypes', function () { // banner with * size (not in rule file so does not do anything) - expect(getFirstMatchingFloor({...basicFloorData}, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor({ ...basicFloorData }, basicBidRequest, { mediaType: 'banner', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 1.0, matchingFloor: 1.0, @@ -404,7 +407,7 @@ describe('the price floors module', function () { matchingRule: 'banner' }); // video with * size (not in rule file so does not do anything) - expect(getFirstMatchingFloor({...basicFloorData}, basicBidRequest, {mediaType: 'video', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor({ ...basicFloorData }, basicBidRequest, { mediaType: 'video', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 5.0, matchingFloor: 5.0, @@ -412,7 +415,7 @@ describe('the price floors module', function () { matchingRule: 'video' }); // native (not in the rule list) with * size (not in rule file so does not do anything) - expect(getFirstMatchingFloor({...basicFloorData}, basicBidRequest, {mediaType: 'native', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor({ ...basicFloorData }, basicBidRequest, { mediaType: 'native', size: '*' })).to.deep.equal({ floorMin: 0, floorRuleValue: 2.5, matchingFloor: 2.5, @@ -423,7 +426,7 @@ describe('the price floors module', function () { handleSetFloorsConfig({ ...minFloorConfigHigh }); - expect(getFirstMatchingFloor({...basicFloorDataHigh}, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor({ ...basicFloorDataHigh }, basicBidRequest, { mediaType: 'banner', size: '*' })).to.deep.equal({ floorMin: 7, floorRuleValue: 1.0, matchingFloor: 7, @@ -434,7 +437,7 @@ describe('the price floors module', function () { handleSetFloorsConfig({ ...minFloorConfigLow }); - expect(getFirstMatchingFloor({...basicFloorDataLow}, basicBidRequest, {mediaType: 'video', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor({ ...basicFloorDataLow }, basicBidRequest, { mediaType: 'video', size: '*' })).to.deep.equal({ floorMin: 2.3, floorRuleValue: 5, matchingFloor: 5, @@ -443,9 +446,9 @@ describe('the price floors module', function () { }); }); it('does not alter cached matched input if conversion occurs', function () { - const inputData = {...basicFloorData}; + const inputData = { ...basicFloorData }; [0.2, 0.4, 0.6, 0.8].forEach(modifier => { - const result = getFirstMatchingFloor(inputData, basicBidRequest, {mediaType: 'banner', size: '*'}); + const result = getFirstMatchingFloor(inputData, basicBidRequest, { mediaType: 'banner', size: '*' }); // result should always be the same expect(result).to.deep.equal({ floorMin: 0, @@ -474,7 +477,7 @@ describe('the price floors module', function () { } } // banner with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: [300, 250]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'banner', size: [300, 250] })).to.deep.equal({ floorMin: 0, floorRuleValue: 1.1, matchingFloor: 1.1, @@ -482,7 +485,7 @@ describe('the price floors module', function () { matchingRule: '300x250' }); // video with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'video', size: [300, 250]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'video', size: [300, 250] })).to.deep.equal({ floorMin: 0, floorRuleValue: 1.1, matchingFloor: 1.1, @@ -490,7 +493,7 @@ describe('the price floors module', function () { matchingRule: '300x250' }); // native (not in the rule list) with 300x600 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'native', size: [600, 300]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'native', size: [600, 300] })).to.deep.equal({ floorMin: 0, floorRuleValue: 4.4, matchingFloor: 4.4, @@ -498,7 +501,7 @@ describe('the price floors module', function () { matchingRule: '600x300' }); // n/a mediaType with a size not in file should go to catch all - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: undefined, size: [1, 1]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: undefined, size: [1, 1] })).to.deep.equal({ floorMin: 0, floorRuleValue: 5.5, matchingFloor: 5.5, @@ -523,7 +526,7 @@ describe('the price floors module', function () { default: 0.5 }); // banner with 300x250 size - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: [300, 250]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'banner', size: [300, 250] })).to.deep.equal({ floorMin: 0, floorRuleValue: 1.1, matchingFloor: 1.1, @@ -531,7 +534,7 @@ describe('the price floors module', function () { matchingRule: 'test_div_1^banner^300x250' }); // video with 300x250 size -> No matching rule so should use default - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'video', size: [300, 250]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'video', size: [300, 250] })).to.deep.equal({ floorMin: 0, floorRuleValue: 0.5, matchingFloor: 0.5, @@ -540,7 +543,7 @@ describe('the price floors module', function () { }); // remove default and should still return the same floor as above since matches are cached delete inputFloorData.default; - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'video', size: [300, 250]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'video', size: [300, 250] })).to.deep.equal({ floorMin: 0, floorRuleValue: 0.5, matchingFloor: 0.5, @@ -549,7 +552,7 @@ describe('the price floors module', function () { }); // update adUnitCode to test_div_2 with weird other params const newBidRequest = { ...basicBidRequest, adUnitCode: 'test_div_2' } - expect(getFirstMatchingFloor(inputFloorData, newBidRequest, {mediaType: 'badmediatype', size: [900, 900]})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, newBidRequest, { mediaType: 'badmediatype', size: [900, 900] })).to.deep.equal({ floorMin: 0, floorRuleValue: 3.3, matchingFloor: 3.3, @@ -559,12 +562,12 @@ describe('the price floors module', function () { }); it('it does not break if floorData has bad values', function () { let inputFloorData = {}; - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'})).to.deep.equal({ + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'banner', size: '*' })).to.deep.equal({ matchingFloor: undefined }); // if default is there use it inputFloorData = normalizeDefault({ default: 5.0 }); - expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, {mediaType: 'banner', size: '*'}).matchingFloor).to.equal(5.0); + expect(getFirstMatchingFloor(inputFloorData, basicBidRequest, { mediaType: 'banner', size: '*' }).matchingFloor).to.equal(5.0); }); describe('with gpt enabled', function () { let gptFloorData; @@ -595,7 +598,7 @@ describe('the price floors module', function () { divId: 'test_div_2' }); indexStub = sinon.stub(auctionManager, 'index'); - indexStub.get(() => stubAuctionIndex({adUnits})) + indexStub.get(() => stubAuctionIndex({ adUnits })) }); afterEach(function () { // reset it so no lingering stuff from other test specs @@ -622,7 +625,7 @@ describe('the price floors module', function () { }); it('picks the gptSlot from the adUnit and does not call the slotMatching', function () { const newBidRequest1 = { ...basicBidRequest, adUnitId: 'au1' }; - adUnits = [{code: newBidRequest1.adUnitCode, adUnitId: 'au1'}]; + adUnits = [{ code: newBidRequest1.adUnitCode, adUnitId: 'au1' }]; utils.deepSetValue(adUnits[0], 'ortb2Imp.ext.data.adserver', { name: 'gam', adslot: '/12345/news/politics' @@ -636,7 +639,7 @@ describe('the price floors module', function () { }); const newBidRequest2 = { ...basicBidRequest, adUnitCode: 'test_div_2', adUnitId: 'au2' }; - adUnits = [{code: newBidRequest2.adUnitCode, adUnitId: newBidRequest2.adUnitId}]; + adUnits = [{ code: newBidRequest2.adUnitCode, adUnitId: newBidRequest2.adUnitId }]; utils.deepSetValue(adUnits[0], 'ortb2Imp.ext.data.adserver', { name: 'gam', adslot: '/12345/news/weather' @@ -774,11 +777,11 @@ describe('the price floors module', function () { let actualAllowedFields = allowedFields; let actualFieldMatchingFunctions = fieldMatchingFunctions; const defaultAllowedFields = [...allowedFields]; - const defaultMatchingFunctions = {...fieldMatchingFunctions}; + const defaultMatchingFunctions = { ...fieldMatchingFunctions }; afterEach(function() { exposedAdUnits = undefined; actualAllowedFields = [...defaultAllowedFields]; - actualFieldMatchingFunctions = {...defaultMatchingFunctions}; + actualFieldMatchingFunctions = { ...defaultMatchingFunctions }; }); it('should not do floor stuff if no resulting floor object can be resolved for auciton', function () { handleSetFloorsConfig({ @@ -804,7 +807,8 @@ describe('the price floors module', function () { data: { ...basicFloorDataLow, noFloorSignalBidders: ['someBidder', 'someOtherBidder'] - }}); + } + }); runStandardAuction(); validateBidRequests(false, { skipped: false, @@ -820,7 +824,8 @@ describe('the price floors module', function () { }) }); it('should not do floor stuff if floors.enforcement is defined by noFloorSignalBidders[]', function() { - handleSetFloorsConfig({ ...basicFloorConfig, + handleSetFloorsConfig({ + ...basicFloorConfig, enforcement: { enforceJS: true, noFloorSignalBidders: ['someBidder', 'someOtherBidder'] @@ -842,7 +847,8 @@ describe('the price floors module', function () { }) }); it('should not do floor stuff and use first floors.data.noFloorSignalBidders if its defined betwen enforcement.noFloorSignalBidders', function() { - handleSetFloorsConfig({ ...basicFloorConfig, + handleSetFloorsConfig({ + ...basicFloorConfig, enforcement: { enforceJS: true, noFloorSignalBidders: ['someBidder'] @@ -867,7 +873,8 @@ describe('the price floors module', function () { }) }); it('it shouldn`t return floor stuff for bidder in the noFloorSignalBidders list', function() { - handleSetFloorsConfig({ ...basicFloorConfig, + handleSetFloorsConfig({ + ...basicFloorConfig, enforcement: { enforceJS: true, }, @@ -893,7 +900,8 @@ describe('the price floors module', function () { }); }) it('it should return floor stuff if we defined wrong bidder name in data.noFloorSignalBidders', function() { - handleSetFloorsConfig({ ...basicFloorConfig, + handleSetFloorsConfig({ + ...basicFloorConfig, enforcement: { enforceJS: true, }, @@ -1016,8 +1024,8 @@ describe('the price floors module', function () { ...basicFloorConfig, data: undefined }); - adUnits[0].floors = {default: 1}; - adUnits[1].floors = {default: 2}; + adUnits[0].floors = { default: 1 }; + adUnits[1].floors = { default: 2 }; expectFloors([1, 2]) }); it('on an adUnit with hidden schema', () => { @@ -1078,7 +1086,7 @@ describe('the price floors module', function () { }); }) it('bidRequests should have getFloor function and flooring meta data when setConfig occurs', function () { - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider'}); + handleSetFloorsConfig({ ...basicFloorConfig, floorProvider: 'floorprovider' }); runStandardAuction(); validateBidRequests(true, { skipped: false, @@ -1301,24 +1309,24 @@ describe('the price floors module', function () { }); }); it('should ignore and reset floor data when provided with invalid data', function () { - handleSetFloorsConfig({...basicFloorConfig}); + handleSetFloorsConfig({ ...basicFloorConfig }); handleSetFloorsConfig({ ...basicFloorConfig, data: { - schema: {fields: ['thisIsNotAllowedSoShouldFail']}, - values: {'*': 1.2}, + schema: { fields: ['thisIsNotAllowedSoShouldFail'] }, + values: { '*': 1.2 }, modelVersion: 'FAIL' } }); runStandardAuction(); - validateBidRequests(false, sinon.match({location: 'noData', skipped: true})); + validateBidRequests(false, sinon.match({ location: 'noData', skipped: true })); }); it('should dynamically add new schema fileds and functions if added via setConfig', function () { let deviceSpoof; handleSetFloorsConfig({ ...basicFloorConfig, data: { - schema: {fields: ['deviceType']}, + schema: { fields: ['deviceType'] }, values: { 'mobile': 1.0, 'desktop': 2.0, @@ -1366,7 +1374,7 @@ describe('the price floors module', function () { }); }); it('Should continue auction of delay is hit without a response from floor provider', function () { - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json//'}}); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json//' } }); // start the auction it should delay and not immediately call `continueAuction` runStandardAuction(); @@ -1404,7 +1412,7 @@ describe('the price floors module', function () { server.respondWith(JSON.stringify(fetchFloorData)); // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // floor provider should be called expect(server.requests.length).to.equal(1); @@ -1444,7 +1452,7 @@ describe('the price floors module', function () { server.respondWith(JSON.stringify(fetchFloorData)); // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorproviderC', auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, floorProvider: 'floorproviderC', auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // floor provider should be called expect(server.requests.length).to.equal(1); @@ -1485,7 +1493,7 @@ describe('the price floors module', function () { server.respondWith(JSON.stringify(fetchFloorData)); // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, floorProvider: 'floorprovider', auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // floor provider should be called expect(server.requests.length).to.equal(1); @@ -1517,7 +1525,7 @@ describe('the price floors module', function () { }); it('Should not break if floor provider returns 404', function () { // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // run the auction and make server respond with 404 server.respond(); @@ -1543,7 +1551,7 @@ describe('the price floors module', function () { server.respondWith('Not valid response'); // run setConfig indicating fetch - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // run the auction and make server respond server.respond(); @@ -1568,8 +1576,8 @@ describe('the price floors module', function () { it('should handle not using fetch correctly', function () { // run setConfig twice indicating fetch server.respondWith(JSON.stringify(basicFloorData)); - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); // log warn should be called and server only should have one request expect(logWarnSpy.calledOnce).to.equal(true); @@ -1578,7 +1586,7 @@ describe('the price floors module', function () { // now we respond and then run again it should work and make another request server.respond(); - handleSetFloorsConfig({...basicFloorConfig, auctionDelay: 250, endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, auctionDelay: 250, endpoint: { url: 'http://www.fakefloorprovider.json/' } }); server.respond(); // now warn still only called once and server called twice @@ -1587,7 +1595,7 @@ describe('the price floors module', function () { // should log error if method is not GET for now expect(logErrorSpy.calledOnce).to.equal(false); - handleSetFloorsConfig({...basicFloorConfig, endpoint: {url: 'http://www.fakefloorprovider.json/', method: 'POST'}}); + handleSetFloorsConfig({ ...basicFloorConfig, endpoint: { url: 'http://www.fakefloorprovider.json/', method: 'POST' } }); expect(logErrorSpy.calledOnce).to.equal(true); }); describe('isFloorsDataValid', function () { @@ -1700,7 +1708,7 @@ describe('the price floors module', function () { inputFloorData.modelGroups[1].modelWeight = 40; // remove values from a model and it should not validate - const tempValues = {...inputFloorData.modelGroups[0].values}; + const tempValues = { ...inputFloorData.modelGroups[0].values }; delete inputFloorData.modelGroups[0].values; expect(isFloorsDataValid(inputFloorData)).to.to.equal(false); inputFloorData.modelGroups[0].values = tempValues; @@ -1731,21 +1739,21 @@ describe('the price floors module', function () { }); // ask for banner - inputParams = {mediaType: 'banner'}; + inputParams = { mediaType: 'banner' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 1.0 }); // ask for video - inputParams = {mediaType: 'video'}; + inputParams = { mediaType: 'video' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 5.0 }); // ask for * - inputParams = {mediaType: '*'}; + inputParams = { mediaType: '*' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 2.5 @@ -1757,7 +1765,7 @@ describe('the price floors module', function () { const req = utils.deepClone(bidRequest); _floorDataForAuction[req.auctionId] = utils.deepClone(basicFloorConfig); - expect(guardTids({bidderCode: 'mock-bidder'}).bidRequest(req).getFloor({})).to.deep.equal({ + expect(guardTids({ bidderCode: 'mock-bidder' }).bidRequest(req).getFloor({})).to.deep.equal({ currency: 'USD', floor: 1.0 }); @@ -1789,28 +1797,28 @@ describe('the price floors module', function () { }); // ask for banner with a size - inputParams = {mediaType: 'banner', size: [300, 600]}; + inputParams = { mediaType: 'banner', size: [300, 600] }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 1.5 }); // ask for video with a size - inputParams = {mediaType: 'video', size: [640, 480]}; + inputParams = { mediaType: 'video', size: [640, 480] }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 4.5 }); // ask for video with a size not in rules (should pick rule which has video and *) - inputParams = {mediaType: 'video', size: [111, 222]}; + inputParams = { mediaType: 'video', size: [111, 222] }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 5.5 }); // ask for native * but no native rule so should use default value if there - inputParams = {mediaType: 'native', size: '*'}; + inputParams = { mediaType: 'native', size: '*' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 10.0 @@ -1824,14 +1832,14 @@ describe('the price floors module', function () { }; // assumes banner * - let inputParams = {mediaType: 'banner'}; + let inputParams = { mediaType: 'banner' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 1.7778 }); // assumes banner * - inputParams = {mediaType: 'video'}; + inputParams = { mediaType: 'video' }; expect(bidRequest.getFloor(inputParams)).to.deep.equal({ currency: 'USD', floor: 1.1112 @@ -2030,18 +2038,18 @@ describe('the price floors module', function () { inverseParams: {} }, 'only mediaType': { - getFloorParams: {mediaType: 'video'}, - inverseParams: {mediaType: 'video'} + getFloorParams: { mediaType: 'video' }, + inverseParams: { mediaType: 'video' } }, 'only size': { - getFloorParams: {mediaType: '*', size: [1, 2]}, - inverseParams: {size: [1, 2]} + getFloorParams: { mediaType: '*', size: [1, 2] }, + inverseParams: { size: [1, 2] } }, 'both': { - getFloorParams: {mediaType: 'banner', size: [1, 2]}, - inverseParams: {mediaType: 'banner', size: [1, 2]} + getFloorParams: { mediaType: 'banner', size: [1, 2] }, + inverseParams: { mediaType: 'banner', size: [1, 2] } } - }).forEach(([t, {getFloorParams, inverseParams}]) => { + }).forEach(([t, { getFloorParams, inverseParams }]) => { it(`should pass inverseFloorAdjustment mediatype and size (${t})`, () => { getGlobal().bidderSettings = { standard: { @@ -2146,23 +2154,23 @@ describe('the price floors module', function () { }; // because bid req only has video, if a bidder asks for a floor for * we can actually give them the right mediaType - expect(inputBidReq.getFloor({mediaType: '*'})).to.deep.equal({ + expect(inputBidReq.getFloor({ mediaType: '*' })).to.deep.equal({ currency: 'USD', floor: 5.0 // 'video': 5.0 }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // Same for if only banner is in the input bid - inputBidReq.mediaTypes = {banner: {}}; - expect(inputBidReq.getFloor({mediaType: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { banner: {} }; + expect(inputBidReq.getFloor({ mediaType: '*' })).to.deep.equal({ currency: 'USD', floor: 3.0 // 'banner': 3.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // if both are present then it will really use the * - inputBidReq.mediaTypes = {banner: {}, video: {}}; - expect(inputBidReq.getFloor({mediaType: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { banner: {}, video: {} }; + expect(inputBidReq.getFloor({ mediaType: '*' })).to.deep.equal({ currency: 'USD', floor: 1.0 // '*': 1.0, }); @@ -2181,47 +2189,47 @@ describe('the price floors module', function () { }; // mediaType is banner and only one size, so if someone asks for banner * we should give them banner 300x250 // instead of banner|* - inputBidReq.mediaTypes = {banner: {sizes: [[300, 250]]}}; - expect(inputBidReq.getFloor({mediaType: 'banner', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { banner: { sizes: [[300, 250]] } }; + expect(inputBidReq.getFloor({ mediaType: 'banner', size: '*' })).to.deep.equal({ currency: 'USD', floor: 2.0 // 'banner|300x250': 2.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // now for video it should look at playersize (prebid core translates playersize into typical array of size arrays) - inputBidReq.mediaTypes = {video: {playerSize: [[728, 90]]}}; - expect(inputBidReq.getFloor({mediaType: 'video', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { video: { playerSize: [[728, 90]] } }; + expect(inputBidReq.getFloor({ mediaType: 'video', size: '*' })).to.deep.equal({ currency: 'USD', floor: 6.0 // 'video|728x90': 6.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // Now if multiple sizes are there, it will actually use * since can't infer - inputBidReq.mediaTypes = {banner: {sizes: [[300, 250], [728, 90]]}}; - expect(inputBidReq.getFloor({mediaType: 'banner', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { banner: { sizes: [[300, 250], [728, 90]] } }; + expect(inputBidReq.getFloor({ mediaType: 'banner', size: '*' })).to.deep.equal({ currency: 'USD', floor: 4.0 // 'banner|*': 4.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // lastly, if you pass in * mediaType and * size it should resolve both if possble - inputBidReq.mediaTypes = {banner: {sizes: [[300, 250]]}}; - expect(inputBidReq.getFloor({mediaType: '*', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { banner: { sizes: [[300, 250]] } }; + expect(inputBidReq.getFloor({ mediaType: '*', size: '*' })).to.deep.equal({ currency: 'USD', floor: 2.0 // 'banner|300x250': 2.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; - inputBidReq.mediaTypes = {video: {playerSize: [[300, 250]]}}; - expect(inputBidReq.getFloor({mediaType: '*', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { video: { playerSize: [[300, 250]] } }; + expect(inputBidReq.getFloor({ mediaType: '*', size: '*' })).to.deep.equal({ currency: 'USD', floor: 5.0 // 'video|300x250': 5.0, }); delete _floorDataForAuction[inputBidReq.auctionId].data.matchingInputs; // now it has both mediaTypes so will use * mediaType and thus not use sizes either - inputBidReq.mediaTypes = {video: {playerSize: [[300, 250]]}, banner: {sizes: [[300, 250]]}}; - expect(inputBidReq.getFloor({mediaType: '*', size: '*'})).to.deep.equal({ + inputBidReq.mediaTypes = { video: { playerSize: [[300, 250]] }, banner: { sizes: [[300, 250]] } }; + expect(inputBidReq.getFloor({ mediaType: '*', size: '*' })).to.deep.equal({ currency: 'USD', floor: 1.0 // '*|*': 1.0, }); @@ -2247,9 +2255,9 @@ describe('the price floors module', function () { }; beforeEach(function () { returnedBidResponse = null; - reject = sinon.stub().returns({status: 'rejected'}); + reject = sinon.stub().returns({ status: 'rejected' }); indexStub = sinon.stub(auctionManager, 'index'); - indexStub.get(() => stubAuctionIndex({adUnits: [adUnit]})); + indexStub.get(() => stubAuctionIndex({ adUnits: [adUnit] })); }); afterEach(() => { @@ -2286,6 +2294,51 @@ describe('the price floors module', function () { expect(reject.calledOnce).to.be.true; expect(returnedBidResponse).to.not.exist; }); + it('enforces floors for all bidders by default', function () { + _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig); + _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 1.0 }; + returnedBidResponse = null; + runBidResponse({ + ...basicBidResponse, + bidderCode: 'rubicon' + }); + expect(reject.calledOnce).to.be.true; + expect(returnedBidResponse).to.equal(null); + }); + it('enforces floors only for configured enforceBidders when provided', function () { + _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig); + _floorDataForAuction[AUCTION_ID].enforcement.enforceBidders = ['rubicon']; + _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 1.0 }; + + runBidResponse({ + ...basicBidResponse, + bidderCode: 'appnexus' + }); + expect(reject.called).to.be.false; + expect(returnedBidResponse).to.haveOwnProperty('floorData'); + + returnedBidResponse = null; + runBidResponse({ + ...basicBidResponse, + bidderCode: 'rubicon' + }); + expect(reject.calledOnce).to.be.true; + expect(returnedBidResponse).to.equal(null); + }); + it('uses adapterCode when checking enforceBidders', function () { + _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig); + _floorDataForAuction[AUCTION_ID].enforcement.enforceBidders = ['rubicon']; + _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 1.0 }; + + runBidResponse({ + ...basicBidResponse, + bidderCode: 'alternateBidder', + adapterCode: 'rubicon' + }); + + expect(reject.calledOnce).to.be.true; + expect(returnedBidResponse).to.equal(null); + }); it('if it finds a rule and does not floor should update the bid accordingly', function () { _floorDataForAuction[AUCTION_ID] = utils.deepClone(basicFloorConfig); _floorDataForAuction[AUCTION_ID].data.values = { 'banner': 0.3 }; @@ -2299,6 +2352,7 @@ describe('the price floors module', function () { cpmAfterAdjustments: 0.5, enforcements: { bidAdjustment: true, + enforceBidders: ['*'], enforceJS: true, enforcePBS: false, floorDeals: false @@ -2336,6 +2390,7 @@ describe('the price floors module', function () { cpmAfterAdjustments: 0.5, enforcements: { bidAdjustment: true, + enforceBidders: ['*'], enforceJS: true, enforcePBS: false, floorDeals: false @@ -2364,6 +2419,7 @@ describe('the price floors module', function () { cpmAfterAdjustments: 7.5, enforcements: { bidAdjustment: true, + enforceBidders: ['*'], enforceJS: true, enforcePBS: false, floorDeals: false @@ -2385,7 +2441,7 @@ describe('the price floors module', function () { }; }); it('should wait 3 seconds before deleting auction floor data', function () { - handleSetFloorsConfig({enabled: true}); + handleSetFloorsConfig({ enabled: true }); _floorDataForAuction[AUCTION_END_EVENT.auctionId] = utils.deepClone(basicFloorConfig); events.emit(EVENTS.AUCTION_END, AUCTION_END_EVENT); // should still be here @@ -2417,7 +2473,7 @@ describe('the price floors module', function () { { code: req.adUnitCode, adUnitId: req.adUnitId, - ortb2Imp: {ext: {data: {adserver: {name: 'gam', adslot: 'slot'}}}} + ortb2Imp: { ext: { data: { adserver: { name: 'gam', adslot: 'slot' } } } } } ] })); @@ -2488,7 +2544,7 @@ describe('setting null as rule value', () => { } _floorDataForAuction[bidRequest.auctionId] = basicFloorConfig; - const inputParams = {mediaType: 'banner', size: [600, 300]}; + const inputParams = { mediaType: 'banner', size: [600, 300] }; expect(bidRequest.getFloor(inputParams)).to.deep.equal(null); }) @@ -2508,12 +2564,12 @@ describe('setting null as rule value', () => { server.respondWith(JSON.stringify(nullFloorData)); let exposedAdUnits; - handleSetFloorsConfig({...basicFloorConfig, floorProvider: 'floorprovider', endpoint: {url: 'http://www.fakefloorprovider.json/'}}); + handleSetFloorsConfig({ ...basicFloorConfig, floorProvider: 'floorprovider', endpoint: { url: 'http://www.fakefloorprovider.json/' } }); const adUnits = [{ cod: 'test_div_1', - mediaTypes: {banner: { sizes: [[600, 300]] }, native: {}}, - bids: [{bidder: 'someBidder', adUnitCode: 'test_div_1'}, {bidder: 'someOtherBidder', adUnitCode: 'test_div_1'}] + mediaTypes: { banner: { sizes: [[600, 300]] }, native: {} }, + bids: [{ bidder: 'someBidder', adUnitCode: 'test_div_1' }, { bidder: 'someOtherBidder', adUnitCode: 'test_div_1' }] }]; requestBidsHook(config => exposedAdUnits = config.adUnits, { @@ -2521,7 +2577,7 @@ describe('setting null as rule value', () => { adUnits }); - const inputParams = {mediaType: 'banner', size: [600, 300]}; + const inputParams = { mediaType: 'banner', size: [600, 300] }; expect(exposedAdUnits[0].bids[0].getFloor(inputParams)).to.deep.equal(null); }); diff --git a/test/spec/modules/prismaBidAdapter_spec.js b/test/spec/modules/prismaBidAdapter_spec.js index a368378a481..e715348f6f0 100644 --- a/test/spec/modules/prismaBidAdapter_spec.js +++ b/test/spec/modules/prismaBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/prismaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/prismaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import { requestBidsHook } from 'modules/consentManagementTcf.js'; @@ -51,25 +51,27 @@ describe('Prisma bid adapter tests', function () { 'bidderWinsCount': 0 }]; - const DISPLAY_BID_RESPONSE = {'body': { - 'responses': [ - { - 'bidId': '4d9e29504f8af6', - 'cpm': 0.437245, - 'width': 300, - 'height': 250, - 'creativeId': '98493581', - 'currency': 'EUR', - 'netRevenue': true, - 'type': 'banner', - 'ttl': 360, - 'uuid': 'ce6d1ee3-2a05-4d7c-b97a-9e62097798ec', - 'bidder': 'appnexus', - 'consent': 1, - 'tagId': 'luvxjvgn' - } - ], - }}; + const DISPLAY_BID_RESPONSE = { + 'body': { + 'responses': [ + { + 'bidId': '4d9e29504f8af6', + 'cpm': 0.437245, + 'width': 300, + 'height': 250, + 'creativeId': '98493581', + 'currency': 'EUR', + 'netRevenue': true, + 'type': 'banner', + 'ttl': 360, + 'uuid': 'ce6d1ee3-2a05-4d7c-b97a-9e62097798ec', + 'bidder': 'appnexus', + 'consent': 1, + 'tagId': 'luvxjvgn' + } + ], + } + }; const VIDEO_BID_REQUEST = [ { @@ -101,25 +103,27 @@ describe('Prisma bid adapter tests', function () { } ] - const VIDEO_BID_RESPONSE = {'body': { - 'responses': [ - { - 'bidId': '2c129e8e01859a', - 'type': 'video', - 'uuid': 'b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5', - 'cpm': 4.5421, - 'width': 1, - 'height': 1, - 'creativeId': '97517771', - 'currency': 'EUR', - 'netRevenue': true, - 'ttl': 360, - 'bidder': 'appnexus', - 'consent': 1, - 'tagId': 'yqsc1tfj' - } - ] - }}; + const VIDEO_BID_RESPONSE = { + 'body': { + 'responses': [ + { + 'bidId': '2c129e8e01859a', + 'type': 'video', + 'uuid': 'b8e7b2f0-c378-479f-aa4f-4f55d5d7d1d5', + 'cpm': 4.5421, + 'width': 1, + 'height': 1, + 'creativeId': '97517771', + 'currency': 'EUR', + 'netRevenue': true, + 'ttl': 360, + 'bidder': 'appnexus', + 'consent': 1, + 'tagId': 'yqsc1tfj' + } + ] + } + }; const DEFAULT_OPTIONS = { gdprConsent: { @@ -242,7 +246,7 @@ describe('Prisma bid adapter tests', function () { expect(syncs).to.have.lengthOf(0); }); it('Verifies user sync with cookies in bid response', function () { - DISPLAY_BID_RESPONSE.body.cookies = [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}]; + DISPLAY_BID_RESPONSE.body.cookies = [{ 'type': 'image', 'url': 'http://www.cookie.sync.org/' }]; var syncs = spec.getUserSyncs({}, [DISPLAY_BID_RESPONSE], DEFAULT_OPTIONS.gdprConsent); expect(syncs).to.have.lengthOf(1); expect(syncs[0]).to.have.property('type').and.to.equal('image'); diff --git a/test/spec/modules/programmaticXBidAdapter_spec.js b/test/spec/modules/programmaticXBidAdapter_spec.js index 2c857efc8fb..83f939bcd27 100644 --- a/test/spec/modules/programmaticXBidAdapter_spec.js +++ b/test/spec/modules/programmaticXBidAdapter_spec.js @@ -1,14 +1,14 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, storage } from 'modules/programmaticXBidAdapter'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js' -import {config} from '../../../src/config.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js' +import { config } from '../../../src/config.js'; import { hashCode, extractPID, @@ -19,7 +19,7 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'netId', 'tdid', 'pubProvidedId', 'intentIqId', 'liveIntentId']; @@ -105,9 +105,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -124,7 +124,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -195,9 +195,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -210,7 +209,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -335,9 +334,9 @@ describe('programmaticXBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -409,9 +408,9 @@ describe('programmaticXBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -457,7 +456,7 @@ describe('programmaticXBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -466,7 +465,7 @@ describe('programmaticXBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.programmaticx.ai/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -474,7 +473,7 @@ describe('programmaticXBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.programmaticx.ai/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -486,7 +485,7 @@ describe('programmaticXBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.programmaticx.ai/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -504,7 +503,7 @@ describe('programmaticXBidAdapter', function () { applicableSections: [7] } - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE], gdprConsent, uspConsent, gppConsent); expect(result).to.deep.equal([{ 'url': 'https://sync.programmaticx.ai/api/sync/image/?cid=testcid123&gdpr=1&gdpr_consent=consent_string&us_privacy=usp_string&coppa=1&gpp=gpp_string&gpp_sid=7', @@ -520,12 +519,12 @@ describe('programmaticXBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -598,9 +597,9 @@ describe('programmaticXBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -621,7 +620,7 @@ describe('programmaticXBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -632,11 +631,11 @@ describe('programmaticXBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -651,7 +650,7 @@ describe('programmaticXBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -666,11 +665,11 @@ describe('programmaticXBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -683,18 +682,18 @@ describe('programmaticXBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -754,7 +753,7 @@ describe('programmaticXBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -770,8 +769,8 @@ describe('programmaticXBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/proxistoreBidAdapter_spec.js b/test/spec/modules/proxistoreBidAdapter_spec.js index 767ef93cf81..c24c80cc41c 100644 --- a/test/spec/modules/proxistoreBidAdapter_spec.js +++ b/test/spec/modules/proxistoreBidAdapter_spec.js @@ -1,167 +1,493 @@ import { expect } from 'chai'; import { spec } from 'modules/proxistoreBidAdapter.js'; -import { newBidder } from 'src/adapters/bidderFactory.js'; -import { config } from '../../../src/config.js'; +import { BANNER } from 'src/mediaTypes.js'; const BIDDER_CODE = 'proxistore'; +const COOKIE_BASE_URL = 'https://abs.proxistore.com/v3/rtb/openrtb'; +const COOKIE_LESS_URL = 'https://abs.cookieless-proxistore.com/v3/rtb/openrtb'; + describe('ProxistoreBidAdapter', function () { const consentString = 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A=='; - const bidderRequest = { + + const baseBidderRequest = { bidderCode: BIDDER_CODE, auctionId: '1025ba77-5463-4877-b0eb-14b205cb9304', bidderRequestId: '10edf38ec1a719', - gdprConsent: { - apiVersion: 2, - gdprApplies: true, - consentString: consentString, - vendorData: { - vendor: { - consents: { - 418: true, - }, + timeout: 1000, + }; + + const gdprConsentWithVendor = { + apiVersion: 2, + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { + 418: true, }, }, }, }; - const bid = { - sizes: [[300, 600]], + + const gdprConsentWithoutVendor = { + apiVersion: 2, + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { + 418: false, + }, + }, + }, + }; + + const gdprConsentNoVendorData = { + apiVersion: 2, + gdprApplies: true, + consentString: consentString, + vendorData: null, + }; + + const baseBid = { + bidder: BIDDER_CODE, params: { website: 'example.fr', language: 'fr', }, - ortb2: { - user: { ext: { data: { segments: [], contextual_categories: {} } } }, + mediaTypes: { + banner: { + sizes: [[300, 600], [300, 250]], + }, }, - auctionId: 442133079, - bidId: 464646969, - transactionId: 511916005, + adUnitCode: 'div-gpt-ad-123', + transactionId: '511916005', + bidId: '464646969', + auctionId: '1025ba77-5463-4877-b0eb-14b205cb9304', }; + + describe('spec properties', function () { + it('should have correct bidder code', function () { + expect(spec.code).to.equal(BIDDER_CODE); + }); + + it('should have correct GVLID', function () { + expect(spec.gvlid).to.equal(418); + }); + + it('should support banner media type', function () { + expect(spec.supportedMediaTypes).to.deep.equal([BANNER]); + }); + + it('should have browsingTopics enabled', function () { + expect(spec.browsingTopics).to.be.true; + }); + + it('should have getUserSyncs function', function () { + expect(spec.getUserSyncs).to.be.a('function'); + }); + }); + describe('isBidRequestValid', function () { - it('it should be true if required params are presents and there is no info in the local storage', function () { - expect(spec.isBidRequestValid(bid)).to.equal(true); + it('should return true when website and language params are present', function () { + expect(spec.isBidRequestValid(baseBid)).to.equal(true); + }); + + it('should return false when website param is missing', function () { + const bid = { ...baseBid, params: { language: 'fr' } }; + expect(spec.isBidRequestValid(bid)).to.equal(false); }); - it('it should be false if the value in the localstorage is less than 5minutes of the actual time', function () { - const date = new Date(); - date.setMinutes(date.getMinutes() - 1); - localStorage.setItem(`PX_NoAds_${bid.params.website}`, date); - expect(spec.isBidRequestValid(bid)).to.equal(true); + + it('should return false when language param is missing', function () { + const bid = { ...baseBid, params: { website: 'example.fr' } }; + expect(spec.isBidRequestValid(bid)).to.equal(false); }); - it('it should be true if the value in the localstorage is more than 5minutes of the actual time', function () { - const date = new Date(); - date.setMinutes(date.getMinutes() - 10); - localStorage.setItem(`PX_NoAds_${bid.params.website}`, date); - expect(spec.isBidRequestValid(bid)).to.equal(true); + + it('should return false when params object is empty', function () { + const bid = { ...baseBid, params: {} }; + expect(spec.isBidRequestValid(bid)).to.equal(false); }); }); + describe('buildRequests', function () { - const url = { - cookieBase: 'https://abs.proxistore.com/v3/rtb/prebid/multi', - cookieLess: - 'https://abs.cookieless-proxistore.com/v3/rtb/prebid/multi', - }; - - let request = spec.buildRequests([bid], bidderRequest); - it('should return a valid object', function () { - expect(request).to.be.an('object'); - expect(request.method).to.exist; - expect(request.url).to.exist; - expect(request.data).to.exist; - }); - it('request method should be POST', function () { - expect(request.method).to.equal('POST'); - }); - it('should have the value consentGiven to true bc we have 418 in the vendor list', function () { - const data = JSON.parse(request.data); - expect(data.gdpr.consentString).equal( - bidderRequest.gdprConsent.consentString - ); - expect(data.gdpr.applies).to.be.true; - expect(data.gdpr.consentGiven).to.be.true; - }); - it('should contain a valid url', function () { - // has gdpr consent - expect(request.url).equal(url.cookieBase); - // doens't have gdpr consent - bidderRequest.gdprConsent.vendorData = null; - - request = spec.buildRequests([bid], bidderRequest); - expect(request.url).equal(url.cookieLess); - - // api v2 - bidderRequest.gdprConsent = { + describe('request structure', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + + it('should return a valid object', function () { + expect(request).to.be.an('object'); + expect(request.method).to.exist; + expect(request.url).to.exist; + expect(request.data).to.exist; + expect(request.options).to.exist; + }); + + it('should use POST method', function () { + expect(request.method).to.equal('POST'); + }); + + it('should have correct options', function () { + expect(request.options.contentType).to.equal('application/json'); + expect(request.options.customHeaders).to.deep.equal({ version: '2.0.0' }); + }); + }); + + describe('OpenRTB data format', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + const data = request.data; + + it('should have valid OpenRTB structure', function () { + expect(data).to.be.an('object'); + expect(data.id).to.be.a('string'); + expect(data.imp).to.be.an('array'); + }); + + it('should have imp array with correct length', function () { + expect(data.imp.length).to.equal(1); + }); + + it('should have imp with banner object', function () { + expect(data.imp[0].banner).to.be.an('object'); + expect(data.imp[0].banner.format).to.be.an('array'); + }); + + it('should include banner formats from bid sizes', function () { + const formats = data.imp[0].banner.format; + expect(formats).to.deep.include({ w: 300, h: 600 }); + expect(formats).to.deep.include({ w: 300, h: 250 }); + }); + + it('should set imp.id to bidId', function () { + expect(data.imp[0].id).to.equal(baseBid.bidId); + }); + + it('should include tmax from bidderRequest timeout', function () { + expect(data.tmax).to.equal(1000); + }); + + it('should include website and language in ext.proxistore', function () { + expect(data.ext).to.be.an('object'); + expect(data.ext.proxistore).to.be.an('object'); + expect(data.ext.proxistore.website).to.equal('example.fr'); + expect(data.ext.proxistore.language).to.equal('fr'); + }); + }); + + describe('endpoint URL selection', function () { + it('should use cookie URL when GDPR consent is given for vendor 418', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.url).to.equal(COOKIE_BASE_URL); + }); + + it('should use cookieless URL when GDPR applies but consent not given', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithoutVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.url).to.equal(COOKIE_LESS_URL); + }); + + it('should use cookieless URL when vendorData is null', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentNoVendorData }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.url).to.equal(COOKIE_LESS_URL); + }); + + it('should use cookie URL when GDPR does not apply', function () { + const bidderRequest = { + ...baseBidderRequest, + gdprConsent: { + gdprApplies: false, + consentString: consentString, + }, + }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.url).to.equal(COOKIE_BASE_URL); + }); + + it('should use cookie URL when no gdprConsent object', function () { + const bidderRequest = { ...baseBidderRequest }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.url).to.equal(COOKIE_BASE_URL); + }); + }); + + describe('withCredentials option', function () { + it('should set withCredentials to true when consent given', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.options.withCredentials).to.be.true; + }); + + it('should set withCredentials to false when consent not given', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithoutVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.options.withCredentials).to.be.false; + }); + + it('should set withCredentials to false when no vendorData', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentNoVendorData }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.options.withCredentials).to.be.false; + }); + + it('should set withCredentials to false when no gdprConsent', function () { + const bidderRequest = { ...baseBidderRequest }; + const request = spec.buildRequests([baseBid], bidderRequest); + expect(request.options.withCredentials).to.be.false; + }); + }); + + describe('multiple bids', function () { + it('should create imp for each bid request', function () { + const secondBid = { + ...baseBid, + bidId: '789789789', + adUnitCode: 'div-gpt-ad-456', + }; + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid, secondBid], bidderRequest); + const data = request.data; + + expect(data.imp.length).to.equal(2); + expect(data.imp[0].id).to.equal(baseBid.bidId); + expect(data.imp[1].id).to.equal(secondBid.bidId); + }); + }); + }); + + describe('interpretResponse', function () { + it('should return empty array for empty response', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + const emptyResponse = { body: null }; + + const bids = spec.interpretResponse(emptyResponse, request); + expect(bids).to.be.an('array'); + expect(bids.length).to.equal(0); + }); + + it('should return empty array for response with no seatbid', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + const response = { body: { id: '123', seatbid: [] } }; + + const bids = spec.interpretResponse(response, request); + expect(bids).to.be.an('array'); + expect(bids.length).to.equal(0); + }); + + it('should correctly parse OpenRTB bid response', function () { + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid], bidderRequest); + const requestData = request.data; + + const serverResponse = { + body: { + id: requestData.id, + seatbid: [{ + seat: 'proxistore', + bid: [{ + id: 'bid-id-1', + impid: baseBid.bidId, + price: 6.25, + adm: '
Ad markup
', + w: 300, + h: 600, + crid: '22c3290b-8cd5-4cd6-8e8c-28a2de180ccd', + dealid: '2021-03_deal123', + adomain: ['advertiser.com'], + }], + }], + cur: 'EUR', + }, + }; + + const bids = spec.interpretResponse(serverResponse, request); + + expect(bids).to.be.an('array'); + expect(bids.length).to.equal(1); + + const bid = bids[0]; + expect(bid.requestId).to.equal(baseBid.bidId); + expect(bid.cpm).to.equal(6.25); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(600); + expect(bid.ad).to.equal('
Ad markup
'); + expect(bid.creativeId).to.equal('22c3290b-8cd5-4cd6-8e8c-28a2de180ccd'); + expect(bid.dealId).to.equal('2021-03_deal123'); + expect(bid.currency).to.equal('EUR'); + expect(bid.netRevenue).to.be.true; + expect(bid.ttl).to.equal(30); + expect(bid.meta.advertiserDomains).to.deep.equal(['advertiser.com']); + }); + + it('should handle multiple bids in response', function () { + const secondBid = { + ...baseBid, + bidId: '789789789', + adUnitCode: 'div-gpt-ad-456', + }; + const bidderRequest = { ...baseBidderRequest, gdprConsent: gdprConsentWithVendor }; + const request = spec.buildRequests([baseBid, secondBid], bidderRequest); + const requestData = request.data; + + const serverResponse = { + body: { + id: requestData.id, + seatbid: [{ + seat: 'proxistore', + bid: [ + { + id: 'bid-id-1', + impid: baseBid.bidId, + price: 6.25, + adm: '
Ad 1
', + w: 300, + h: 600, + crid: 'creative-1', + }, + { + id: 'bid-id-2', + impid: secondBid.bidId, + price: 4.50, + adm: '
Ad 2
', + w: 300, + h: 250, + crid: 'creative-2', + }, + ], + }], + cur: 'EUR', + }, + }; + + const bids = spec.interpretResponse(serverResponse, request); + + expect(bids).to.be.an('array'); + expect(bids.length).to.equal(2); + expect(bids[0].requestId).to.equal(baseBid.bidId); + expect(bids[0].cpm).to.equal(6.25); + expect(bids[1].requestId).to.equal(secondBid.bidId); + expect(bids[1].cpm).to.equal(4.50); + }); + }); + + describe('getUserSyncs', function () { + const SYNC_BASE_URL = 'https://abs.proxistore.com/v3/rtb/sync'; + + it('should return empty array when GDPR applies and consent not given', function () { + const syncOptions = { pixelEnabled: true, iframeEnabled: true }; + const gdprConsent = { gdprApplies: true, - allowAuctionWithoutConsent: true, consentString: consentString, vendorData: { vendor: { - consents: { - 418: true, - }, + consents: { 418: false }, }, }, - apiVersion: 2, }; - // has gdpr consent - request = spec.buildRequests([bid], bidderRequest); - expect(request.url).equal(url.cookieBase); - - bidderRequest.gdprConsent.vendorData.vendor = {}; - request = spec.buildRequests([bid], bidderRequest); - expect(request.url).equal(url.cookieLess); - }); - it('should have a property a length of bids equal to one if there is only one bid', function () { - const data = JSON.parse(request.data); - expect(data.hasOwnProperty('bids')).to.be.true; - expect(data.bids).to.be.an('array'); - expect(data.bids.length).equal(1); - expect(data.bids[0].hasOwnProperty('id')).to.be.true; - expect(data.bids[0].sizes).to.be.an('array'); - }); - it('should correctly set bidfloor on imp when getfloor in scope', function () { - let data = JSON.parse(request.data); - expect(data.bids[0].floor).to.be.null; - - bid.params['bidFloor'] = 1; - let req = spec.buildRequests([bid], bidderRequest); - data = JSON.parse(req.data); - expect(data.bids[0].floor).equal(1); - bid.getFloor = function () { - return { currency: 'USD', floor: 1.0 }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(0); + }); + + it('should return pixel sync when pixelEnabled and consent given', function () { + const syncOptions = { pixelEnabled: true, iframeEnabled: false }; + const gdprConsent = { + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { 418: true }, + }, + }, }; - req = spec.buildRequests([bid], bidderRequest); - data = JSON.parse(req.data); - expect(data.bids[0].floor).to.be.null; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(1); + expect(syncs[0].type).to.equal('image'); + expect(syncs[0].url).to.include(`${SYNC_BASE_URL}/image`); + expect(syncs[0].url).to.include('gdpr=1'); + expect(syncs[0].url).to.include(`gdpr_consent=${encodeURIComponent(consentString)}`); }); - }); - describe('interpretResponse', function () { - const emptyResponseParam = { body: [] }; - const fakeResponseParam = { - body: [ - { - ad: '', - cpm: 6.25, - creativeId: '22c3290b-8cd5-4cd6-8e8c-28a2de180ccd', - currency: 'EUR', - dealId: '2021-03_a63ec55e-b9bb-4ca4-b2c9-f456be67e656', - height: 600, - netRevenue: true, - requestId: '3543724f2a033c9', - segments: [], - ttl: 10, - vastUrl: null, - vastXml: null, - width: 300, + + it('should return iframe sync when iframeEnabled and consent given', function () { + const syncOptions = { pixelEnabled: false, iframeEnabled: true }; + const gdprConsent = { + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { 418: true }, + }, }, - ], - }; - - it('should always return an array', function () { - let response = spec.interpretResponse(emptyResponseParam, bid); - expect(response).to.be.an('array'); - expect(response.length).equal(0); - response = spec.interpretResponse(fakeResponseParam, bid); - expect(response).to.be.an('array'); - expect(response.length).equal(1); + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.include(`${SYNC_BASE_URL}/iframe`); + }); + + it('should return both syncs when both enabled and consent given', function () { + const syncOptions = { pixelEnabled: true, iframeEnabled: true }; + const gdprConsent = { + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { 418: true }, + }, + }, + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(2); + expect(syncs[0].type).to.equal('image'); + expect(syncs[1].type).to.equal('iframe'); + }); + + it('should return syncs when GDPR does not apply', function () { + const syncOptions = { pixelEnabled: true, iframeEnabled: true }; + const gdprConsent = { + gdprApplies: false, + consentString: consentString, + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(2); + expect(syncs[0].url).to.include('gdpr=0'); + }); + + it('should return syncs when no gdprConsent provided', function () { + const syncOptions = { pixelEnabled: true, iframeEnabled: true }; + + const syncs = spec.getUserSyncs(syncOptions, [], undefined); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(2); + }); + + it('should return empty array when no sync options enabled', function () { + const syncOptions = { pixelEnabled: false, iframeEnabled: false }; + const gdprConsent = { + gdprApplies: true, + consentString: consentString, + vendorData: { + vendor: { + consents: { 418: true }, + }, + }, + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent); + expect(syncs).to.be.an('array'); + expect(syncs.length).to.equal(0); }); }); }); diff --git a/test/spec/modules/pubCircleBidAdapter_spec.js b/test/spec/modules/pubCircleBidAdapter_spec.js index 97953192a6e..ebf53063c52 100644 --- a/test/spec/modules/pubCircleBidAdapter_spec.js +++ b/test/spec/modules/pubCircleBidAdapter_spec.js @@ -432,7 +432,7 @@ describe('PubCircleBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -441,9 +441,7 @@ describe('PubCircleBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.pubcircle.ai/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -452,7 +450,7 @@ describe('PubCircleBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.pubcircle.ai/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/publinkIdSystem_spec.js b/test/spec/modules/publinkIdSystem_spec.js index fda67f24864..c3c990972ab 100644 --- a/test/spec/modules/publinkIdSystem_spec.js +++ b/test/spec/modules/publinkIdSystem_spec.js @@ -1,8 +1,8 @@ -import {publinkIdSubmodule} from 'modules/publinkIdSystem.js'; -import {getCoreStorageManager, getStorageManager} from '../../../src/storageManager.js'; -import {server} from 'test/mocks/xhr.js'; +import { publinkIdSubmodule } from 'modules/publinkIdSystem.js'; +import { getCoreStorageManager, getStorageManager } from '../../../src/storageManager.js'; +import { server } from 'test/mocks/xhr.js'; import sinon from 'sinon'; -import {parseUrl} from '../../../src/utils.js'; +import { parseUrl } from '../../../src/utils.js'; const storage = getCoreStorageManager(); @@ -11,7 +11,7 @@ describe('PublinkIdSystem', () => { describe('decode', () => { it('decode', () => { const result = publinkIdSubmodule.decode(TEST_COOKIE_VALUE); - expect(result).deep.equals({publinkId: TEST_COOKIE_VALUE}); + expect(result).deep.equals({ publinkId: TEST_COOKIE_VALUE }); }); }); @@ -19,8 +19,8 @@ describe('PublinkIdSystem', () => { const PUBLINK_COOKIE = '_publink'; const PUBLINK_SRV_COOKIE = '_publink_srv'; const EXP = Date.now() + 60 * 60 * 24 * 7 * 1000; - const COOKIE_VALUE = {publink: 'publinkCookieValue', exp: EXP}; - const LOCAL_VALUE = {publink: 'publinkLocalStorageValue', exp: EXP}; + const COOKIE_VALUE = { publink: 'publinkCookieValue', exp: EXP }; + const LOCAL_VALUE = { publink: 'publinkLocalStorageValue', exp: EXP }; const COOKIE_EXPIRATION = (new Date(Date.now() + 60 * 60 * 24 * 1000)).toUTCString(); const DELETE_COOKIE = 'Thu, 01 Jan 1970 00:00:01 GMT'; it('publink srv cookie', () => { @@ -64,7 +64,7 @@ describe('PublinkIdSystem', () => { }); describe('getId', () => { - const serverResponse = {publink: 'ec0xHT3yfAOnykP64Qf0ORSi7LjNT1wju04ZSCsoPBekOJdBwK-0Zl_lXKDNnzhauC4iszBc-PvA1Be6IMlh1QocA'}; + const serverResponse = { publink: 'ec0xHT3yfAOnykP64Qf0ORSi7LjNT1wju04ZSCsoPBekOJdBwK-0Zl_lXKDNnzhauC4iszBc-PvA1Be6IMlh1QocA' }; it('no config', () => { const result = publinkIdSubmodule.getId(); expect(result).to.exist; @@ -79,7 +79,7 @@ describe('PublinkIdSystem', () => { }); it('Has cached id', () => { - const config = {storage: {type: 'cookie'}}; + const config = { storage: { type: 'cookie' } }; const submoduleCallback = publinkIdSubmodule.getId(config, undefined, TEST_COOKIE_VALUE).callback; submoduleCallback(callbackSpy); @@ -98,7 +98,7 @@ describe('PublinkIdSystem', () => { }); it('Request path has priority', () => { - const config = {storage: {type: 'cookie'}, params: {e: 'ca11c0ca7', site_id: '102030'}}; + const config = { storage: { type: 'cookie' }, params: { e: 'ca11c0ca7', site_id: '102030' } }; const submoduleCallback = publinkIdSubmodule.getId(config, undefined, TEST_COOKIE_VALUE).callback; submoduleCallback(callbackSpy); @@ -117,8 +117,8 @@ describe('PublinkIdSystem', () => { }); it('Fetch with GDPR consent data', () => { - const config = {storage: {type: 'cookie'}, params: {e: 'ca11c0ca7', site_id: '102030'}}; - const consentData = {gdpr: {gdprApplies: 1, consentString: 'myconsentstring'}}; + const config = { storage: { type: 'cookie' }, params: { e: 'ca11c0ca7', site_id: '102030' } }; + const consentData = { gdpr: { gdprApplies: 1, consentString: 'myconsentstring' } }; const submoduleCallback = publinkIdSubmodule.getId(config, consentData).callback; submoduleCallback(callbackSpy); @@ -140,7 +140,7 @@ describe('PublinkIdSystem', () => { }); it('server doesnt respond', () => { - const config = {storage: {type: 'cookie'}, params: {e: 'ca11c0ca7'}}; + const config = { storage: { type: 'cookie' }, params: { e: 'ca11c0ca7' } }; const submoduleCallback = publinkIdSubmodule.getId(config).callback; submoduleCallback(callbackSpy); @@ -157,8 +157,8 @@ describe('PublinkIdSystem', () => { }); it('reject plain email address', () => { - const config = {storage: {type: 'cookie'}, params: {e: 'tester@test.com'}}; - const consentData = {gdprApplies: 1, consentString: 'myconsentstring'}; + const config = { storage: { type: 'cookie' }, params: { e: 'tester@test.com' } }; + const consentData = { gdprApplies: 1, consentString: 'myconsentstring' }; const submoduleCallback = publinkIdSubmodule.getId(config, consentData).callback; submoduleCallback(callbackSpy); @@ -171,8 +171,8 @@ describe('PublinkIdSystem', () => { const callbackSpy = sinon.spy(); it('Fetch with usprivacy data', () => { - const config = {storage: {type: 'cookie'}, params: {e: 'ca11c0ca7', api_key: 'abcdefg'}}; - const submoduleCallback = publinkIdSubmodule.getId(config, {usp: '1YNN'}).callback; + const config = { storage: { type: 'cookie' }, params: { e: 'ca11c0ca7', api_key: 'abcdefg' } }; + const submoduleCallback = publinkIdSubmodule.getId(config, { usp: '1YNN' }).callback; submoduleCallback(callbackSpy); const request = server.requests[0]; diff --git a/test/spec/modules/publirBidAdapter_spec.js b/test/spec/modules/publirBidAdapter_spec.js index 0265fbb4020..f6d42328ea4 100644 --- a/test/spec/modules/publirBidAdapter_spec.js +++ b/test/spec/modules/publirBidAdapter_spec.js @@ -186,7 +186,7 @@ describe('publirAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -199,7 +199,7 @@ describe('publirAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -207,7 +207,7 @@ describe('publirAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); @@ -268,15 +268,15 @@ describe('publirAdapter', function () { 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -290,20 +290,20 @@ describe('publirAdapter', function () { 'sua': { 'platform': { 'brand': 'macOS', - 'version': [ '12', '4', '0' ] + 'version': ['12', '4', '0'] }, 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, diff --git a/test/spec/modules/pubmaticBidAdapter_spec.js b/test/spec/modules/pubmaticBidAdapter_spec.js index 2ed65dd7311..598251724bc 100644 --- a/test/spec/modules/pubmaticBidAdapter_spec.js +++ b/test/spec/modules/pubmaticBidAdapter_spec.js @@ -3,7 +3,7 @@ import { spec, cpmAdjustment, addViewabilityToImp, shouldAddDealTargeting } from import * as utils from 'src/utils.js'; import { bidderSettings } from 'src/bidderSettings.js'; import { config } from 'src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('PubMatic adapter', () => { let firstBid, videoBid, firstResponse, response, videoResponse, firstAliasBid; @@ -53,7 +53,7 @@ describe('PubMatic adapter', () => { js: 1, connectiontype: 6 }, - site: {domain: 'ebay.com', page: 'https://ebay.com', publisher: {id: '5670'}}, + site: { domain: 'ebay.com', page: 'https://ebay.com', publisher: { id: '5670' } }, source: {}, user: { ext: { @@ -136,7 +136,7 @@ describe('PubMatic adapter', () => { js: 1, connectiontype: 6 }, - site: {domain: 'ebay.com', page: 'https://ebay.com', publisher: {id: '5670'}}, + site: { domain: 'ebay.com', page: 'https://ebay.com', publisher: { id: '5670' } }, source: {}, user: { ext: { @@ -195,7 +195,7 @@ describe('PubMatic adapter', () => { }, 'dealid': 'PUBDEAL1', 'mtype': 2, - 'params': {'outstreamAU': 'outstreamAU', 'renderer': 'renderer_test_pubmatic'} + 'params': { 'outstreamAU': 'outstreamAU', 'renderer': 'renderer_test_pubmatic' } }] }; firstResponse = { @@ -255,7 +255,7 @@ describe('PubMatic adapter', () => { js: 1, connectiontype: 6 }, - site: {domain: 'ebay.com', page: 'https://ebay.com'}, + site: { domain: 'ebay.com', page: 'https://ebay.com' }, source: {}, user: { ext: { @@ -287,7 +287,7 @@ describe('PubMatic adapter', () => { js: 1, connectiontype: 6 }, - site: {domain: 'ebay.com', page: 'https://ebay.com'}, + site: { domain: 'ebay.com', page: 'https://ebay.com' }, source: {}, user: { ext: { @@ -1140,7 +1140,7 @@ describe('PubMatic adapter', () => { ] }; beforeEach(() => { - bidderRequest.ortb2.regs = {ext: { dsa }}; + bidderRequest.ortb2.regs = { ext: { dsa } }; }); it('should have DSA in regs.ext', () => { diff --git a/test/spec/modules/pubmaticIdSystem_spec.js b/test/spec/modules/pubmaticIdSystem_spec.js index 3d6b4ab40ea..d8fb99a8a1c 100644 --- a/test/spec/modules/pubmaticIdSystem_spec.js +++ b/test/spec/modules/pubmaticIdSystem_spec.js @@ -52,7 +52,7 @@ describe('pubmaticIdSystem', () => { const expectedURL = 'https://image6.pubmatic.com/AdServer/UCookieSetPug?oid=5&p=12345&publisherId=12345&gdpr=0&gdpr_consent=&src=pbjs_uid&ver=1&coppa=0&us_privacy=&gpp=&gpp_sid='; expect(request.url).to.equal(expectedURL); - expect(completeCallback.calledOnceWithExactly({id: '6C3F0AB9-AE82-45C2-AD6F-9721E542DC4A'})).to.be.true; + expect(completeCallback.calledOnceWithExactly({ id: '6C3F0AB9-AE82-45C2-AD6F-9721E542DC4A' })).to.be.true; }); it('should log an error if configuration is invalid', () => { diff --git a/test/spec/modules/pubperfAnalyticsAdapter_spec.js b/test/spec/modules/pubperfAnalyticsAdapter_spec.js index 0d75c64f97f..7e273b54c45 100644 --- a/test/spec/modules/pubperfAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubperfAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import pubperfAnalytics from 'modules/pubperfAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; -import {expectEvents, fireEvents} from '../../helpers/analytics.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; +import { expectEvents, fireEvents } from '../../helpers/analytics.js'; const events = require('src/events'); const utils = require('src/utils.js'); diff --git a/test/spec/modules/pubriseBidAdapter_spec.js b/test/spec/modules/pubriseBidAdapter_spec.js index 786f6a98b5c..37aaa964602 100644 --- a/test/spec/modules/pubriseBidAdapter_spec.js +++ b/test/spec/modules/pubriseBidAdapter_spec.js @@ -482,7 +482,7 @@ describe('PubriseBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -491,9 +491,7 @@ describe('PubriseBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.pubrise.ai/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -502,7 +500,7 @@ describe('PubriseBidAdapter', function () { expect(syncData[0].url).to.equal('https://sync.pubrise.ai/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/pubstackAnalyticsAdapter_spec.js b/test/spec/modules/pubstackAnalyticsAdapter_spec.js index 6e532698d8b..8ef362192c3 100644 --- a/test/spec/modules/pubstackAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubstackAnalyticsAdapter_spec.js @@ -2,7 +2,7 @@ import * as utils from 'src/utils.js'; import pubstackAnalytics from '../../../modules/pubstackAnalyticsAdapter.js'; import adapterManager from 'src/adapterManager'; import * as events from 'src/events'; -import {expectEvents} from '../../helpers/analytics.js'; +import { expectEvents } from '../../helpers/analytics.js'; describe('Pubstack Analytics Adapter', () => { const scope = utils.getWindowSelf(); diff --git a/test/spec/modules/pubstackBidAdapter_spec.js b/test/spec/modules/pubstackBidAdapter_spec.js new file mode 100644 index 00000000000..1f8143e47fa --- /dev/null +++ b/test/spec/modules/pubstackBidAdapter_spec.js @@ -0,0 +1,348 @@ +import { expect } from 'chai'; +import { spec } from 'modules/pubstackBidAdapter'; +import * as utils from 'src/utils.js'; +import { config } from 'src/config.js'; +import { hook } from 'src/hook.js'; +import 'src/prebid.js'; +import 'modules/consentManagementTcf.js'; +import 'modules/consentManagementUsp.js'; +import 'modules/consentManagementGpp.js'; + +describe('pubstackBidAdapter', function () { + const baseBidRequest = { + adUnitCode: 'adunit-code', + auctionId: 'auction-1', + bidId: 'bid-1', + bidder: 'pubstack', + bidderRequestId: 'request-1', + mediaTypes: { banner: { sizes: [[300, 250]] } }, + params: { + siteId: 'site-123', + adUnitName: 'adunit-1' + }, + sizes: [[300, 250]], + transactionId: 'transaction-1' + }; + + const baseBidderRequest = { + gdprConsent: { + gdprApplies: true, + consentString: 'consent-string', + vendorData: { + purpose: { + consents: { 1: true } + } + } + }, + uspConsent: '1YYN', + gppConsent: { + gppString: 'gpp-string', + applicableSections: [7, 8] + }, + refererInfo: { + referer: 'https://example.com' + } + }; + + const clone = (obj) => JSON.parse(JSON.stringify(obj)); + + const createBidRequest = (overrides = {}) => { + const bidRequest = clone(baseBidRequest); + const { params = {}, ...otherOverrides } = overrides; + Object.assign(bidRequest, otherOverrides); + bidRequest.params = { + ...bidRequest.params, + ...params + }; + return bidRequest; + }; + + const createBidderRequest = (bidRequest, overrides = {}) => ({ + ...clone(baseBidderRequest), + bids: [bidRequest], + ...overrides + }); + + const extractBids = (result) => Array.isArray(result) ? result : result?.bids; + + const findSyncForSite = (syncs, siteId) => + syncs.find((sync) => new URL(sync.url).searchParams.get('siteId') === siteId); + + const getDecodedSyncPayload = (sync) => + JSON.parse(atob(new URL(sync.url).searchParams.get('consent'))); + + before(() => { + hook.ready(); + }); + + beforeEach(function () { + config.resetConfig(); + }); + + afterEach(function () { + config.resetConfig(); + }); + + describe('isBidRequestValid', function () { + it('returns true when required params are present', function () { + expect(spec.isBidRequestValid(createBidRequest())).to.equal(true); + }); + + it('returns false for invalid params when debug is disabled', function () { + config.setConfig({ debug: false }); + expect(spec.isBidRequestValid(createBidRequest({ params: { siteId: undefined } }))).to.equal(false); + expect(spec.isBidRequestValid(createBidRequest({ params: { adUnitName: undefined } }))).to.equal(false); + }); + + it('returns true for invalid params when debug is enabled', function () { + config.setConfig({ debug: true }); + expect(spec.isBidRequestValid(createBidRequest({ params: { siteId: undefined } }))).to.equal(true); + expect(spec.isBidRequestValid(createBidRequest({ params: { adUnitName: undefined } }))).to.equal(true); + }); + }); + + describe('buildRequests', function () { + it('builds a POST request with ORTB data and bidder extensions', function () { + const bidRequest = createBidRequest(); + const bidderRequest = createBidderRequest(bidRequest); + const request = spec.buildRequests([bidRequest], bidderRequest); + + expect(request.method).to.equal('POST'); + expect(request.url).to.equal('https://node.pbstck.com/openrtb2/auction?siteId=site-123'); + expect(utils.deepAccess(request, 'data.site.publisher.id')).to.equal('site-123'); + expect(utils.deepAccess(request, 'data.test')).to.equal(0); + expect(request.data.imp).to.have.lengthOf(1); + expect(utils.deepAccess(request, 'data.imp.0.id')).to.equal('bid-1'); + expect(utils.deepAccess(request, 'data.imp.0.ext.prebid.bidder.pubstack.adUnitName')).to.equal('adunit-1'); + expect(utils.deepAccess(request, 'data.imp.0.ext.prebid.placement.code')).to.equal('adunit-code'); + expect(utils.deepAccess(request, 'data.imp.0.ext.prebid.placement.viewability')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.imp.0.ext.prebid.placement.viewportDistance')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.imp.0.ext.prebid.placement.height')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.ext.prebid.version')).to.be.a('string'); + expect(utils.deepAccess(request, 'data.ext.prebid.request.count')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.ext.prebid.request.timeoutCount')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.ext.prebid.page.tabActive')).to.be.a('boolean'); + expect(utils.deepAccess(request, 'data.ext.prebid.page.height')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.ext.prebid.page.viewportHeight')).to.be.a('number'); + expect(utils.deepAccess(request, 'data.ext.prebid.page.timeFromNavigation')).to.be.a('number'); + }); + + it('sets test to 1 when prebid debug mode is enabled', function () { + config.setConfig({ debug: true }); + const bidRequest = createBidRequest({ bidId: 'bid-debug' }); + const bidderRequest = createBidderRequest(bidRequest); + const request = spec.buildRequests([bidRequest], bidderRequest); + + expect(utils.deepAccess(request, 'data.test')).to.equal(1); + }); + + it('increments request counter for each call', function () { + const firstBidRequest = createBidRequest({ bidId: 'bid-counter-1' }); + const firstRequest = spec.buildRequests([firstBidRequest], createBidderRequest(firstBidRequest)); + const secondBidRequest = createBidRequest({ + bidId: 'bid-counter-2', + adUnitCode: 'adunit-code-2', + params: { adUnitName: 'adunit-2' } + }); + const secondRequest = spec.buildRequests([secondBidRequest], createBidderRequest(secondBidRequest)); + + expect(utils.deepAccess(secondRequest, 'data.ext.prebid.request.count')) + .to.equal(utils.deepAccess(firstRequest, 'data.ext.prebid.request.count') + 1); + }); + + it('updates timeout count after onTimeout callback', function () { + const bidRequest = createBidRequest({ bidId: 'bid-timeout-rate-1' }); + const firstRequest = spec.buildRequests([bidRequest], createBidderRequest(bidRequest)); + expect(utils.deepAccess(firstRequest, 'data.ext.prebid.request.timeoutCount')).to.equal(0); + + spec.onTimeout([]); + + const secondBidRequest = createBidRequest({ bidId: 'bid-timeout-rate-2' }); + const secondRequest = spec.buildRequests([secondBidRequest], createBidderRequest(secondBidRequest)); + expect(utils.deepAccess(secondRequest, 'data.ext.prebid.request.timeoutCount')).to.equal(1); + }); + }); + + describe('interpretResponse', function () { + it('returns empty array when response has no body', function () { + const bidRequest = createBidRequest(); + const request = spec.buildRequests([bidRequest], createBidderRequest(bidRequest)); + const bids = spec.interpretResponse({ body: null }, request); + expect(bids).to.be.an('array'); + expect(bids).to.have.lengthOf(0); + }); + + it('maps ORTB bid responses into prebid bids', function () { + const bidRequest = createBidRequest(); + const request = spec.buildRequests([bidRequest], createBidderRequest(bidRequest)); + const serverResponse = { + body: { + id: 'resp-1', + cur: 'USD', + seatbid: [ + { + bid: [ + { + impid: 'bid-1', + mtype: 1, + price: 1.23, + w: 300, + h: 250, + adm: '
ad
', + crid: 'creative-1' + } + ] + } + ] + } + }; + + const result = spec.interpretResponse(serverResponse, request); + const bids = extractBids(result); + expect(bids).to.have.lengthOf(1); + expect(bids[0]).to.include({ + requestId: 'bid-1', + cpm: 1.23, + width: 300, + height: 250, + ad: '
ad
', + creativeId: 'creative-1' + }); + expect(bids[0]).to.have.property('currency', 'USD'); + }); + + it('returns no bids when ORTB response impid does not match request imp ids', function () { + const bidRequest = createBidRequest({ bidId: 'bid-match-required' }); + const request = spec.buildRequests([bidRequest], createBidderRequest(bidRequest)); + const serverResponse = { + body: { + seatbid: [{ + bid: [{ + impid: 'unknown-imp-id', + price: 2.5, + w: 300, + h: 250, + adm: '
ad
', + crid: 'creative-unknown' + }] + }] + } + }; + + expect(extractBids(spec.interpretResponse(serverResponse, request))).to.deep.equal([]); + }); + }); + + describe('getUserSyncs', function () { + it('returns iframe sync with encoded consent payload and site id', function () { + const bidRequest = createBidRequest(); + const bidderRequest = createBidderRequest(bidRequest); + spec.buildRequests([bidRequest], bidderRequest); + + const syncs = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: true }, + [], + bidderRequest.gdprConsent, + bidderRequest.uspConsent, + bidderRequest.gppConsent + ); + + const siteSync = findSyncForSite(syncs, 'site-123'); + expect(siteSync).to.not.equal(undefined); + expect(siteSync.type).to.equal('iframe'); + expect(siteSync.url).to.include('https://cdn.pbstck.com/async_usersync.html'); + + const consentPayload = getDecodedSyncPayload(siteSync); + expect(consentPayload).to.deep.equal({ + gdprConsentString: 'consent-string', + gdprApplies: true, + uspConsent: '1YYN', + gpp: 'gpp-string', + gpp_sid: [7, 8] + }); + }); + + it('returns image sync when iframe sync is disabled', function () { + const bidRequest = createBidRequest({ bidId: 'bid-pixel' }); + const bidderRequest = createBidderRequest(bidRequest); + spec.buildRequests([bidRequest], bidderRequest); + + const syncs = spec.getUserSyncs( + { iframeEnabled: false, pixelEnabled: true }, + [], + bidderRequest.gdprConsent, + bidderRequest.uspConsent, + bidderRequest.gppConsent + ); + + const siteSync = findSyncForSite(syncs, 'site-123'); + expect(siteSync).to.not.equal(undefined); + expect(siteSync.type).to.equal('image'); + expect(siteSync.url).to.include('https://cdn.pbstck.com/async_usersync.png'); + }); + + it('returns no syncs when both iframe and pixel sync are disabled', function () { + const bidRequest = createBidRequest({ bidId: 'bid-disabled-syncs' }); + const bidderRequest = createBidderRequest(bidRequest); + spec.buildRequests([bidRequest], bidderRequest); + + const syncs = spec.getUserSyncs( + { iframeEnabled: false, pixelEnabled: false }, + [], + bidderRequest.gdprConsent, + bidderRequest.uspConsent, + bidderRequest.gppConsent + ); + + expect(syncs).to.deep.equal([]); + }); + + it('includes sync entries for each seen site id', function () { + const bidA = createBidRequest({ + bidId: 'bid-site-a', + adUnitCode: 'ad-site-a', + params: { siteId: 'site-a', adUnitName: 'adunit-a' } + }); + const bidB = createBidRequest({ + bidId: 'bid-site-b', + adUnitCode: 'ad-site-b', + params: { siteId: 'site-b', adUnitName: 'adunit-b' } + }); + + spec.buildRequests([bidA], createBidderRequest(bidA)); + spec.buildRequests([bidB], createBidderRequest(bidB)); + + const syncs = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: false }, + [], + baseBidderRequest.gdprConsent, + baseBidderRequest.uspConsent, + baseBidderRequest.gppConsent + ); + const siteIds = syncs.map((sync) => new URL(sync.url).searchParams.get('siteId')); + + expect(siteIds).to.include('site-a'); + expect(siteIds).to.include('site-b'); + }); + + it('supports null consent objects in the sync payload', function () { + const bidRequest = createBidRequest({ + bidId: 'bid-null-consent', + params: { siteId: 'site-null-consent', adUnitName: 'adunit-null-consent' } + }); + spec.buildRequests([bidRequest], createBidderRequest(bidRequest)); + + const syncs = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: false }, + [], + null, + null, + null + ); + + const siteSync = findSyncForSite(syncs, 'site-null-consent'); + expect(siteSync).to.not.equal(undefined); + expect(getDecodedSyncPayload(siteSync)).to.deep.equal({ uspConsent: null }); + }); + }); +}); diff --git a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js index 35284fbdd87..730624e08bd 100644 --- a/test/spec/modules/pubwiseAnalyticsAdapter_spec.js +++ b/test/spec/modules/pubwiseAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import pubwiseAnalytics from 'modules/pubwiseAnalyticsAdapter.js'; -import {expectEvents} from '../../helpers/analytics.js'; -import {server} from '../../mocks/xhr.js'; +import { expectEvents } from '../../helpers/analytics.js'; +import { server } from '../../mocks/xhr.js'; import { EVENTS } from 'src/constants.js'; const events = require('src/events'); @@ -17,17 +17,17 @@ describe('PubWise Prebid Analytics', function () { provider: 'pubwiseanalytics', options: { site: ['b1ccf317-a6fc-428d-ba69-0c9c208aa61c'], - custom: {'c_script_type': 'test-script-type', 'c_host': 'test-host', 'c_slot1': 'test-slot1', 'c_slot2': 'test-slot2', 'c_slot3': 'test-slot3', 'c_slot4': 'test-slot4'} + custom: { 'c_script_type': 'test-script-type', 'c_host': 'test-host', 'c_slot1': 'test-slot1', 'c_slot2': 'test-slot2', 'c_slot3': 'test-slot3', 'c_slot4': 'test-slot4' } } }; - mock.AUCTION_INIT = {auctionId: '53c35d77-bd62-41e7-b920-244140e30c77'}; + mock.AUCTION_INIT = { auctionId: '53c35d77-bd62-41e7-b920-244140e30c77' }; mock.AUCTION_INIT_EXTRAS = { auctionId: '53c35d77-bd62-41e7-b920-244140e30c77', adUnitCodes: 'not empty', adUnits: '', bidderRequests: ['0'], bidsReceived: '0', - config: {test: 'config'}, + config: { test: 'config' }, noBids: 'no bids today', winningBids: 'winning bids', extraProp: 'extraProp retained' @@ -35,7 +35,7 @@ describe('PubWise Prebid Analytics', function () { beforeEach(function() { sandbox = sinon.createSandbox(); - clock = sandbox.useFakeTimers({shouldClearNativeTimers: true}); + clock = sandbox.useFakeTimers({ shouldClearNativeTimers: true }); sandbox.stub(events, 'getEvents').returns([]); requests = server.requests; diff --git a/test/spec/modules/pubxBidAdapter_spec.js b/test/spec/modules/pubxBidAdapter_spec.js index f0148bb1d06..0561987b348 100644 --- a/test/spec/modules/pubxBidAdapter_spec.js +++ b/test/spec/modules/pubxBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/pubxBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec } from 'modules/pubxBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; describe('pubxAdapter', function () { diff --git a/test/spec/modules/pulsepointBidAdapter_spec.js b/test/spec/modules/pulsepointBidAdapter_spec.js index a13b285b69b..c2724bfedbc 100644 --- a/test/spec/modules/pulsepointBidAdapter_spec.js +++ b/test/spec/modules/pulsepointBidAdapter_spec.js @@ -1,8 +1,8 @@ /* eslint dot-notation:0, quote-props:0 */ -import {expect} from 'chai'; -import {spec} from 'modules/pulsepointBidAdapter.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {deepClone} from '../../../src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/pulsepointBidAdapter.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { deepClone } from '../../../src/utils.js'; import 'modules/consentManagementTcf'; import 'modules/consentManagementUsp'; import 'modules/userId/index'; @@ -134,20 +134,26 @@ describe('PulsePoint Adapter Tests', function () { bidfloor: 1.5, badv: ['cocacola.com', 'lays.com'] }, - ortb2: {source: {ext: {schain: { - 'ver': '1.0', - 'complete': 1, - 'nodes': [ - { - 'asi': 'exchange1.com', - 'sid': '1234', - 'hp': 1, - 'rid': 'bid-request-1', - 'name': 'publisher', - 'domain': 'publisher.com' + ortb2: { + source: { + ext: { + schain: { + 'ver': '1.0', + 'complete': 1, + 'nodes': [ + { + 'asi': 'exchange1.com', + 'sid': '1234', + 'hp': 1, + 'rid': 'bid-request-1', + 'name': 'publisher', + 'domain': 'publisher.com' + } + ] + } } - ] - }}}} + } + } }]; const bidderRequest = { @@ -174,11 +180,11 @@ describe('PulsePoint Adapter Tests', function () { // slot 1 expect(ortbRequest.imp[0].tagid).to.equal('t10000'); expect(ortbRequest.imp[0].banner).to.not.equal(null); - expect(ortbRequest.imp[0].banner.format).to.deep.eq([{'w': 728, 'h': 90}, {'w': 160, 'h': 600}]); + expect(ortbRequest.imp[0].banner.format).to.deep.eq([{ 'w': 728, 'h': 90 }, { 'w': 160, 'h': 600 }]); // slot 2 expect(ortbRequest.imp[1].tagid).to.equal('t20000'); expect(ortbRequest.imp[1].banner).to.not.equal(null); - expect(ortbRequest.imp[1].banner.format).to.deep.eq([{'w': 728, 'h': 90}]); + expect(ortbRequest.imp[1].banner.format).to.deep.eq([{ 'w': 728, 'h': 90 }]); }); it('Verify parse response', async function () { @@ -199,7 +205,7 @@ describe('PulsePoint Adapter Tests', function () { }] }] }; - const bids = spec.interpretResponse({body: ortbResponse}, request); + const bids = spec.interpretResponse({ body: ortbResponse }, request); expect(bids).to.have.lengthOf(1); // verify first bid const bid = bids[0]; @@ -218,7 +224,7 @@ describe('PulsePoint Adapter Tests', function () { it('Verify full passback', function () { const request = spec.buildRequests(slotConfigs, bidderRequest); - const bids = spec.interpretResponse({body: null}, request) + const bids = spec.interpretResponse({ body: null }, request) expect(bids).to.have.lengthOf(0); }); @@ -266,11 +272,11 @@ describe('PulsePoint Adapter Tests', function () { const ortbRequest = request.data; const nativeResponse = { assets: [ - {id: 1, img: {type: 3, url: 'https://images.cdn.brand.com/123'}}, - {id: 2, title: {text: 'Ad Title'}}, - {id: 3, data: {type: 1, value: 'Sponsored By: Brand'}} + { id: 1, img: { type: 3, url: 'https://images.cdn.brand.com/123' } }, + { id: 2, title: { text: 'Ad Title' } }, + { id: 3, data: { type: 1, value: 'Sponsored By: Brand' } } ], - link: {url: 'https://brand.clickme.com/'}, + link: { url: 'https://brand.clickme.com/' }, imptrackers: ['https://imp1.trackme.com/', 'https://imp1.contextweb.com/'] }; @@ -284,7 +290,7 @@ describe('PulsePoint Adapter Tests', function () { }] }] }; - const bids = spec.interpretResponse({body: ortbResponse}, request); + const bids = spec.interpretResponse({ body: ortbResponse }, request); // verify bid const bid = bids[0]; expect(bid.cpm).to.equal(1.25); diff --git a/test/spec/modules/pwbidBidAdapter_spec.js b/test/spec/modules/pwbidBidAdapter_spec.js index 25dd79a224e..60d70e3ae1f 100644 --- a/test/spec/modules/pwbidBidAdapter_spec.js +++ b/test/spec/modules/pwbidBidAdapter_spec.js @@ -1,7 +1,7 @@ // import or require modules necessary for the test, e.g.: -import {expect} from 'chai'; -import {spec, _checkVideoPlacement, _checkMediaType, _parseAdSlot} from 'modules/pwbidBidAdapter.js'; // _ functions exported only for testing so maintaining the JS convention of _ to indicate the intent +import { expect } from 'chai'; +import { spec, _checkVideoPlacement, _checkMediaType, _parseAdSlot } from 'modules/pwbidBidAdapter.js'; // _ functions exported only for testing so maintaining the JS convention of _ to indicate the intent import * as utils from 'src/utils.js'; const sampleRequestBanner = { @@ -495,7 +495,7 @@ describe('PubWiseAdapter', function () { // endpointBidRequest.forEach((bidRequest) => { // bidRequest.params.endpoint_url = newEndpoint; // }); - const result = spec.buildRequests(endpointBidRequest, {auctionId: 'placeholder'}); + const result = spec.buildRequests(endpointBidRequest, { auctionId: 'placeholder' }); expect(result.url).to.equal(referenceEndpoint); }); @@ -505,7 +505,7 @@ describe('PubWiseAdapter', function () { endpointBidRequest.forEach((bidRequest) => { bidRequest.params.endpoint_url = newEndpoint; }); - const result = spec.buildRequests(endpointBidRequest, {auctionId: 'placeholder'}); + const result = spec.buildRequests(endpointBidRequest, { auctionId: 'placeholder' }); expect(result.url).to.equal(newEndpoint); }); }); @@ -560,7 +560,7 @@ describe('PubWiseAdapter', function () { describe('Handling Request Construction', function () { it('bid requests are not mutable', function() { const sourceBidRequest = utils.deepClone(sampleValidBidRequests); - spec.buildRequests(sampleValidBidRequests, {auctionId: 'placeholder'}); + spec.buildRequests(sampleValidBidRequests, { auctionId: 'placeholder' }); expect(sampleValidBidRequests).to.deep.equal(sourceBidRequest, 'Should be unedited as they are used elsewhere'); }); it('should handle complex bidRequest', function() { @@ -578,15 +578,15 @@ describe('PubWiseAdapter', function () { describe('Identifies Media Types', function () { it('identifies native adm type', function() { const adm = '{"ver":"1.2","assets":[{"title":{"text":"PubWise Test"}},{"img":{"type":3,"url":"http://www.pubwise.io"}},{"img":{"type":1,"url":"http://www.pubwise.io"}},{"data":{"type":2,"value":"PubWise Test Desc"}},{"data":{"type":1,"value":"PubWise.io"}}],"link":{"url":""}}'; - const newBid = {mediaType: 'unknown'}; - _checkMediaType({adm}, newBid); + const newBid = { mediaType: 'unknown' }; + _checkMediaType({ adm }, newBid); expect(newBid.mediaType).to.equal('native', adm + ' Is a Native adm'); }); it('identifies banner adm type', function() { let adm = '

PubWise Test Bid

'; - let newBid = {mediaType: 'unknown'}; - _checkMediaType({adm}, newBid); + let newBid = { mediaType: 'unknown' }; + _checkMediaType({ adm }, newBid); expect(newBid.mediaType).to.equal('banner', adm + ' Is a Banner adm'); }); }); @@ -602,7 +602,7 @@ describe('PubWiseAdapter', function () { describe('Properly Handles Response', function () { it('handles response with muiltiple responses', function() { // the request when it comes back is on the data object - const pbResponse = spec.interpretResponse(sampleRTBResponse, {'data': sampleRequest}) + const pbResponse = spec.interpretResponse(sampleRTBResponse, { 'data': sampleRequest }) expect(pbResponse).to.deep.equal(samplePBBidObjects); }); }); diff --git a/test/spec/modules/pxyzBidAdapter_spec.js b/test/spec/modules/pxyzBidAdapter_spec.js index 2ce6ed0140b..ed16e244168 100644 --- a/test/spec/modules/pxyzBidAdapter_spec.js +++ b/test/spec/modules/pxyzBidAdapter_spec.js @@ -70,7 +70,7 @@ describe('pxyzBidAdapter', function () { expect(Object.keys(data.imp[0].ext)).to.have.members(['appnexus', 'pxyz']); expect([banner.w, banner.h]).to.deep.equal([300, 250]); - expect(banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); expect(request.url).to.equal(URL); expect(request.method).to.equal('POST'); }); @@ -145,7 +145,7 @@ describe('pxyzBidAdapter', function () { describe('interpretResponse', function () { const response = { 'id': 'bidd_id', - 'seatbid': [ { + 'seatbid': [{ 'bid': [ { 'id': '4434762738980910431', @@ -153,7 +153,7 @@ describe('pxyzBidAdapter', function () { 'price': 1, 'adid': '91673066', 'adm': '', - 'adomain': [ 'pg.xyz' ], + 'adomain': ['pg.xyz'], 'iurl': 'http://pgxyz.com/cr?id=91673066', 'cid': 'c_id', 'crid': 'c_rid', @@ -197,14 +197,14 @@ describe('pxyzBidAdapter', function () { } } ]; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); expect(result[0].meta.advertiserDomains).to.deep.equal(expectedResponse[0].meta.advertiserDomains); }); it('handles nobid response', function () { const response = undefined; - const result = spec.interpretResponse({ body: response }, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); }); diff --git a/test/spec/modules/qortexRtdProvider_spec.js b/test/spec/modules/qortexRtdProvider_spec.js index 3f6379af822..56a857e0876 100644 --- a/test/spec/modules/qortexRtdProvider_spec.js +++ b/test/spec/modules/qortexRtdProvider_spec.js @@ -12,7 +12,7 @@ import { requestContextData, windowPostMessageReceived } from '../../../modules/qortexRtdProvider.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; import { cloneDeep } from 'lodash'; describe('qortexRtdProvider', () => { @@ -71,12 +71,12 @@ describe('qortexRtdProvider', () => { const QortexPostMessageInitialized = { target: 'QORTEX-PREBIDJS-RTD-MODULE', message: 'CX-BID-ENRICH-INITIALIZED', - params: {groupConfig: {data: true}} + params: { groupConfig: { data: true } } } const QortexPostMessageContext = { target: 'QORTEX-PREBIDJS-RTD-MODULE', message: 'DISPATCH-CONTEXT', - params: {context: {data: true}} + params: { context: { data: true } } } const invalidTypeQortexEvent = { detail: { @@ -136,7 +136,7 @@ describe('qortexRtdProvider', () => { } beforeEach(() => { - ortb2Stub = sinon.stub(reqBidsConfig, 'ortb2Fragments').value({bidder: {}, global: {}}) + ortb2Stub = sinon.stub(reqBidsConfig, 'ortb2Fragments').value({ bidder: {}, global: {} }) logWarnSpy = sinon.spy(utils, 'logWarn'); logMessageSpy = sinon.spy(utils, 'logMessage'); }) @@ -291,14 +291,14 @@ describe('qortexRtdProvider', () => { }) it('Properly sends analytics event with valid config', () => { - const testData = {auctionId: reqBidsConfig.auctionId, data: 'data'}; + const testData = { auctionId: reqBidsConfig.auctionId, data: 'data' }; module.onAuctionEndEvent(testData); }) }) describe('requestContextData', () => { before(() => { - setContextData({data: true}); + setContextData({ data: true }); }) after(() => { @@ -400,11 +400,11 @@ describe('qortexRtdProvider', () => { }) it('processes incoming qortex component "initialize" message', () => { - windowPostMessageReceived({data: QortexPostMessageInitialized}) + windowPostMessageReceived({ data: QortexPostMessageInitialized }) }) it('processes incoming qortex component "context" message', () => { - windowPostMessageReceived({data: QortexPostMessageContext}) + windowPostMessageReceived({ data: QortexPostMessageContext }) }) }) }) diff --git a/test/spec/modules/qtBidAdapter_spec.js b/test/spec/modules/qtBidAdapter_spec.js index 279962d0d3c..b2b7511cb18 100644 --- a/test/spec/modules/qtBidAdapter_spec.js +++ b/test/spec/modules/qtBidAdapter_spec.js @@ -481,7 +481,7 @@ describe('QTBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -490,9 +490,7 @@ describe('QTBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.qt.io/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0') }); it('Should return array of objects with proper sync config , include CCPA', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -501,7 +499,7 @@ describe('QTBidAdapter', function () { expect(syncData[0].url).to.equal('https://cs.qt.io/image?pbjs=1&ccpa_consent=1---&coppa=0') }); it('Should return array of objects with proper sync config , include GPP', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'abc123', applicableSections: [8] }); diff --git a/test/spec/modules/quantcastBidAdapter_spec.js b/test/spec/modules/quantcastBidAdapter_spec.js index dbf6b2c9ef4..7414999eb88 100644 --- a/test/spec/modules/quantcastBidAdapter_spec.js +++ b/test/spec/modules/quantcastBidAdapter_spec.js @@ -13,7 +13,7 @@ import { import { newBidder } from '../../../src/adapters/bidderFactory.js'; import { parseUrl } from 'src/utils.js'; import { config } from 'src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('Quantcast adapter', function () { const quantcastAdapter = newBidder(qcSpec); @@ -378,15 +378,15 @@ describe('Quantcast adapter', function () { it('parses multi-format bid request', function () { bidRequest.mediaTypes = { - banner: {sizes: [[300, 250], [728, 90], [250, 250], [468, 60], [320, 50]]}, + banner: { sizes: [[300, 250], [728, 90], [250, 250], [468, 60], [320, 50]] }, native: { - image: {required: true, sizes: [150, 50]}, - title: {required: true, len: 80}, - sponsoredBy: {required: true}, - clickUrl: {required: true}, - privacyLink: {required: false}, - body: {required: true}, - icon: {required: true, sizes: [50, 50]} + image: { required: true, sizes: [150, 50] }, + title: { required: true, len: 80 }, + sponsoredBy: { required: true }, + clickUrl: { required: true }, + privacyLink: { required: false }, + body: { required: true }, + icon: { required: true, sizes: [50, 50] } }, video: { context: 'outstream', @@ -402,11 +402,11 @@ describe('Quantcast adapter', function () { banner: { battr: [1, 2], sizes: [ - {width: 300, height: 250}, - {width: 728, height: 90}, - {width: 250, height: 250}, - {width: 468, height: 60}, - {width: 320, height: 50} + { width: 300, height: 250 }, + { width: 728, height: 90 }, + { width: 250, height: 250 }, + { width: 468, height: 60 }, + { width: 320, height: 50 } ] }, placementCode: 'div-gpt-ad-1438287399331-0', diff --git a/test/spec/modules/quantcastIdSystem_spec.js b/test/spec/modules/quantcastIdSystem_spec.js index 157c00e7567..24710e63388 100644 --- a/test/spec/modules/quantcastIdSystem_spec.js +++ b/test/spec/modules/quantcastIdSystem_spec.js @@ -1,9 +1,9 @@ import { quantcastIdSubmodule, storage, firePixel, hasCCPAConsent, hasGDPRConsent, checkTCFv2 } from 'modules/quantcastIdSystem.js'; import * as utils from 'src/utils.js'; -import {coppaDataHandler} from 'src/adapterManager'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; +import { coppaDataHandler } from 'src/adapterManager'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; describe('QuantcastId module', function () { beforeEach(function() { @@ -21,13 +21,13 @@ describe('QuantcastId module', function () { it('getId() should return a quantcast id when the Quantcast first party cookie exists', function () { sinon.stub(storage, 'getCookie').returns('P0-TestFPA'); const id = quantcastIdSubmodule.getId(); - expect(id).to.be.deep.equal({id: {quantcastId: 'P0-TestFPA'}}); + expect(id).to.be.deep.equal({ id: { quantcastId: 'P0-TestFPA' } }); storage.getCookie.restore(); }); it('getId() should return an empty id when the Quantcast first party cookie is missing', function () { const id = quantcastIdSubmodule.getId(); - expect(id).to.be.deep.equal({id: undefined}); + expect(id).to.be.deep.equal({ id: undefined }); }); }); @@ -92,7 +92,7 @@ describe('Quantcast CCPA consent check', function() { describe('Quantcast GDPR consent check', function() { it("returns true when GDPR doesn't apply", function() { - expect(hasGDPRConsent({gdprApplies: false})).to.equal(true); + expect(hasGDPRConsent({ gdprApplies: false })).to.equal(true); }); it('returns false if denied consent, even if special purpose 1 treatment is true in DE', function() { diff --git a/test/spec/modules/qwarryBidAdapter_spec.js b/test/spec/modules/qwarryBidAdapter_spec.js index ae930277476..00e5ab4594a 100644 --- a/test/spec/modules/qwarryBidAdapter_spec.js +++ b/test/spec/modules/qwarryBidAdapter_spec.js @@ -103,7 +103,7 @@ describe('qwarryBidAdapter', function () { expect(bidderRequest.method).to.equal('POST') expect(bidderRequest.data.requestId).to.equal('123') expect(bidderRequest.data.referer).to.equal('http://test.com/path.html') - expect(bidderRequest.data.schain).to.deep.contains({ver: '1.0', complete: 1, nodes: [{asi: 'qwarry.com', sid: '00001', hp: 1}]}) + expect(bidderRequest.data.schain).to.deep.contains({ ver: '1.0', complete: 1, nodes: [{ asi: 'qwarry.com', sid: '00001', hp: 1 }] }) expect(bidderRequest.data.bids).to.deep.contains({ bidId: '456', zoneToken: 'e64782a4-8e68-4c38-965b-80ccf115d46f', pos: 7, sizes: [{ width: 100, height: 200 }, { width: 300, height: 400 }] }) expect(bidderRequest.data.gdprConsent).to.deep.contains({ consentRequired: true, consentString: 'BOJ8RZsOJ8RZsABAB8AAAAAZ+A==' }) expect(bidderRequest.options.customHeaders).to.deep.equal({ 'Rtb-Direct': true }) diff --git a/test/spec/modules/r2b2AnalytiscAdapter_spec.js b/test/spec/modules/r2b2AnalytiscAdapter_spec.js index 1cc675aded5..9098cf10c13 100644 --- a/test/spec/modules/r2b2AnalytiscAdapter_spec.js +++ b/test/spec/modules/r2b2AnalytiscAdapter_spec.js @@ -1,15 +1,16 @@ -import r2b2Analytics, {resetAnalyticAdapter} from '../../../modules/r2b2AnalyticsAdapter.js'; +import r2b2Analytics, { resetAnalyticAdapter } from '../../../modules/r2b2AnalyticsAdapter.js'; import { expect } from 'chai'; -import {EVENTS, AD_RENDER_FAILED_REASON, REJECTION_REASON} from 'src/constants.js'; +import { EVENTS, AD_RENDER_FAILED_REASON, REJECTION_REASON } from 'src/constants.js'; import * as pbEvents from 'src/events.js'; import * as ajax from 'src/ajax.js'; import * as utils from 'src/utils'; -import {getGlobal} from 'src/prebidGlobal'; +import { getGlobal } from 'src/prebidGlobal'; import * as prebidGlobal from 'src/prebidGlobal'; const adapterManager = require('src/adapterManager').default; -const { NO_BID, AUCTION_INIT, BID_REQUESTED, BID_TIMEOUT, BID_RESPONSE, BID_REJECTED, BIDDER_DONE, +const { + NO_BID, AUCTION_INIT, BID_REQUESTED, BID_TIMEOUT, BID_RESPONSE, BID_REJECTED, BIDDER_DONE, AUCTION_END, BID_WON, SET_TARGETING, STALE_RENDER, AD_RENDER_SUCCEEDED, AD_RENDER_FAILED, BID_VIEWABLE } = EVENTS; @@ -30,10 +31,10 @@ const AD_UNIT_1 = { }, 'bids': [{ 'bidder': 'r2b2', - 'params': {'pid': R2B2_PID_1} + 'params': { 'pid': R2B2_PID_1 } }, { 'bidder': 'adf', - 'params': {'mid': 1799592} + 'params': { 'mid': 1799592 } }], 'sizes': BANNER_SETTING_1.sizes, 'transactionId': AD_UNIT_1_TID, @@ -50,7 +51,7 @@ const AD_UNIT_2 = { }, 'bids': [{ 'bidder': 'r2b2', - 'params': {'pid': R2B2_PID_2} + 'params': { 'pid': R2B2_PID_2 } }, { 'bidder': 'stroeerCore', 'params': { 'sid': '9532ef8d-e630-45a9-88f6-3eb3eb265d58' } @@ -71,7 +72,7 @@ const R2B2_BIDDER_REQUEST = { 'bids': [ { 'bidder': 'r2b2', - 'params': {'pid': R2B2_PID_1}, + 'params': { 'pid': R2B2_PID_1 }, 'mediaTypes': { 'banner': BANNER_SETTING_1 }, 'adUnitCode': AD_UNIT_1_CODE, 'transactionId': '0b3464bb-d80a-490e-8367-a65201a37ba3', @@ -82,7 +83,7 @@ const R2B2_BIDDER_REQUEST = { }, { 'bidder': 'r2b2', - 'params': {'pid': R2B2_PID_2}, + 'params': { 'pid': R2B2_PID_2 }, 'mediaTypes': { 'banner': BANNER_SETTING_2 }, 'adUnitCode': AD_UNIT_2_CODE, 'transactionId': 'c8c3643c-9de0-43ea-bcd6-cc0072ec9b45', @@ -274,7 +275,7 @@ const MOCK = { } function fireEvents(events) { return events.map((ev, i) => { - ev = Array.isArray(ev) ? ev : [ev, {i: i}]; + ev = Array.isArray(ev) ? ev : [ev, { i: i }]; pbEvents.emit.apply(null, ev) return ev; }); @@ -286,7 +287,7 @@ function expectEvents(events, sandbox) { to: { beTrackedBy(trackFn) { events.forEach(([eventType, args]) => { - sandbox.assert.calledWithMatch(trackFn, sandbox.match({eventType, args})); + sandbox.assert.calledWithMatch(trackFn, sandbox.match({ eventType, args })); }); }, beBundledTo(bundleFn) { @@ -553,7 +554,7 @@ describe('r2b2 Analytics', function () { expect(adformBidRequest.d).to.be.deep.equal({ ai: AUCTION_ID, b: 'adf', - u: {[AD_UNIT_1_CODE]: 1} + u: { [AD_UNIT_1_CODE]: 1 } }); done(); @@ -599,7 +600,7 @@ describe('r2b2 Analytics', function () { expect(timeoutEvent.d).to.be.deep.equal({ ai: AUCTION_ID, b: { - r2b2: {[AD_UNIT_1_CODE]: 2} + r2b2: { [AD_UNIT_1_CODE]: 2 } } }); @@ -649,7 +650,7 @@ describe('r2b2 Analytics', function () { sz: '300x100', bi: R2B2_AD_UNIT_2_BID.requestId, }], - u: {[AD_UNIT_2_CODE]: {b: {r2b2: 1}}}, + u: { [AD_UNIT_2_CODE]: { b: { r2b2: 1 } } }, o: 1, bc: 1, nbc: 0, diff --git a/test/spec/modules/r2b2BidAdapter_spec.js b/test/spec/modules/r2b2BidAdapter_spec.js index 2d506ab8dc3..56f761b5056 100644 --- a/test/spec/modules/r2b2BidAdapter_spec.js +++ b/test/spec/modules/r2b2BidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec, internal as r2b2, internal} from 'modules/r2b2BidAdapter.js'; +import { expect } from 'chai'; +import { spec, internal as r2b2, internal } from 'modules/r2b2BidAdapter.js'; import * as utils from '../../../src/utils.js'; import 'modules/userId/index.js'; @@ -46,11 +46,11 @@ describe('R2B2 adapter', function () { const id2 = { pid: 'd/g/p/1' }; const id2Object = { d: 'd', g: 'g', p: 'p', m: 1 }; const badId = { pid: 'd/g/' }; - const bid1 = { bidId: bidId1, bidder, params: [ id1 ] }; - const bid2 = { bidId: bidId2, bidder, params: [ id2 ] }; - const bidWithBadSetup = { bidId: bidId3, bidder, params: [ badId ] }; - const bidForeign1 = { bidId: bidId4, bidder: foreignBidder, params: [ { id: 'abc' } ] }; - const bidForeign2 = { bidId: bidId5, bidder: foreignBidder, params: [ { id: 'xyz' } ] }; + const bid1 = { bidId: bidId1, bidder, params: [id1] }; + const bid2 = { bidId: bidId2, bidder, params: [id2] }; + const bidWithBadSetup = { bidId: bidId3, bidder, params: [badId] }; + const bidForeign1 = { bidId: bidId4, bidder: foreignBidder, params: [{ id: 'abc' }] }; + const bidForeign2 = { bidId: bidId5, bidder: foreignBidder, params: [{ id: 'xyz' }] }; const fakeTime = 1234567890; const cacheBusterRegex = /[\?&]cb=([^&]+)/; let bidStub, time; @@ -91,7 +91,7 @@ describe('R2B2 adapter', function () { }, site: {}, device: {}, - source: {ext: {schain: schain}} + source: { ext: { schain: schain } } }, }, { bidder: 'r2b2', @@ -128,7 +128,7 @@ describe('R2B2 adapter', function () { }, site: {}, device: {}, - source: {ext: {schain: schain}} + source: { ext: { schain: schain } } }, }]; bidderRequest = { @@ -150,7 +150,7 @@ describe('R2B2 adapter', function () { }, site: {}, device: {}, - source: {ext: {schain: schain}} + source: { ext: { schain: schain } } }, gdprConsent: { consentString: 'consent-string', @@ -191,7 +191,7 @@ describe('R2B2 adapter', function () { requestForInterpretResponse = { data: { imp: [ - {id: impId} + { id: impId } ] }, bids @@ -202,51 +202,51 @@ describe('R2B2 adapter', function () { const bid = {}; it('should return false when missing required "pid" param', function () { - bid.params = {random: 'param'}; + bid.params = { random: 'param' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {d: 'd', g: 'g', p: 'p', m: 1}; + bid.params = { d: 'd', g: 'g', p: 'p', m: 1 }; expect(spec.isBidRequestValid(bid)).to.equal(false) }); it('should return false when "pid" is malformed', function () { - bid.params = {pid: 'pid'}; + bid.params = { pid: 'pid' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: '///'}; + bid.params = { pid: '///' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: '/g/p/m'}; + bid.params = { pid: '/g/p/m' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: 'd//p/m'}; + bid.params = { pid: 'd//p/m' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: 'd/g//m'}; + bid.params = { pid: 'd/g//m' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: 'd/p/'}; + bid.params = { pid: 'd/p/' }; expect(spec.isBidRequestValid(bid)).to.equal(false); - bid.params = {pid: 'd/g/p/m/t'}; + bid.params = { pid: 'd/g/p/m/t' }; expect(spec.isBidRequestValid(bid)).to.equal(false); }); it('should return true when "pid" is a correct dgpm', function () { - bid.params = {pid: 'd/g/p/m'}; + bid.params = { pid: 'd/g/p/m' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true when type is blank', function () { - bid.params = {pid: 'd/g/p/'}; + bid.params = { pid: 'd/g/p/' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true when type is missing', function () { - bid.params = {pid: 'd/g/p'}; + bid.params = { pid: 'd/g/p' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true when "pid" is a number', function () { - bid.params = {pid: 12356}; + bid.params = { pid: 12356 }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true when "pid" is a numeric string', function () { - bid.params = {pid: '12356'}; + bid.params = { pid: '12356' }; expect(spec.isBidRequestValid(bid)).to.equal(true); }); it('should return true for selfpromo unit', function () { - bid.params = {pid: 'selfpromo'}; + bid.params = { pid: 'selfpromo' }; expect(spec.isBidRequestValid(bid)).to.equal(true) }); }); @@ -269,8 +269,8 @@ describe('R2B2 adapter', function () { it('should pass correct parameters', function () { const requests = spec.buildRequests([bids[0]], bidderRequest); - const {data} = requests[0]; - const {imp, device, site, source, ext, cur, test} = data; + const { data } = requests[0]; + const { imp, device, site, source, ext, cur, test } = data; expect(imp).to.be.an('array').that.has.lengthOf(1); expect(device).to.be.an('object'); expect(site).to.be.an('object'); @@ -282,15 +282,15 @@ describe('R2B2 adapter', function () { it('should pass correct imp', function () { const requests = spec.buildRequests([bids[0]], bidderRequest); - const {data} = requests[0]; - const {imp} = data; + const { data } = requests[0]; + const { imp } = data; expect(imp).to.be.an('array').that.has.lengthOf(1); expect(imp[0]).to.be.an('object'); const bid = imp[0]; expect(bid.id).to.equal('20917a54ee9858'); - expect(bid.banner).to.deep.equal({topframe: 0, format: [{w: 300, h: 250}]}); + expect(bid.banner).to.deep.equal({ topframe: 0, format: [{ w: 300, h: 250 }] }); expect(bid.ext).to.be.an('object'); - expect(bid.ext.r2b2).to.deep.equal({d: 'example.com', g: 'generic', p: '300x250', m: 1}); + expect(bid.ext.r2b2).to.deep.equal({ d: 'example.com', g: 'generic', p: '300x250', m: 1 }); }); it('should map type correctly', function () { @@ -330,27 +330,27 @@ describe('R2B2 adapter', function () { it('should pass correct parameters for test ad', function () { const testAdBid = bids[0]; - testAdBid.params = {pid: 'selfpromo'}; + testAdBid.params = { pid: 'selfpromo' }; const requests = spec.buildRequests([testAdBid], bidderRequest); - const {data} = requests[0]; - const {imp} = data; + const { data } = requests[0]; + const { imp } = data; expect(imp).to.be.an('array').that.has.lengthOf(1); expect(imp[0]).to.be.an('object'); const bid = imp[0]; expect(bid.ext).to.be.an('object'); - expect(bid.ext.r2b2).to.deep.equal({d: 'test', g: 'test', p: 'selfpromo', m: 0, 'selfpromo': 1}); + expect(bid.ext.r2b2).to.deep.equal({ d: 'test', g: 'test', p: 'selfpromo', m: 0, 'selfpromo': 1 }); }); it('should pass multiple bids', function () { const requests = spec.buildRequests(bids, bidderRequest); expect(requests).to.be.an('array').that.has.lengthOf(1); - const {data} = requests[0]; - const {imp} = data; + const { data } = requests[0]; + const { imp } = data; expect(imp).to.be.an('array').that.has.lengthOf(bids.length); const bid1 = imp[0]; - expect(bid1.ext.r2b2).to.deep.equal({d: 'example.com', g: 'generic', p: '300x250', m: 1}); + expect(bid1.ext.r2b2).to.deep.equal({ d: 'example.com', g: 'generic', p: '300x250', m: 1 }); const bid2 = imp[1]; - expect(bid2.ext.r2b2).to.deep.equal({d: 'example.com', g: 'generic', p: '300x600', m: 0}); + expect(bid2.ext.r2b2).to.deep.equal({ d: 'example.com', g: 'generic', p: '300x600', m: 0 }); }); it('should set up internal variables', function () { @@ -359,15 +359,15 @@ describe('R2B2 adapter', function () { const bid2Id = bids[1].bidId; expect(r2b2.placementsToSync).to.be.an('array').that.has.lengthOf(2); expect(r2b2.mappedParams).to.have.property(bid1Id); - expect(r2b2.mappedParams[bid1Id]).to.deep.equal({d: 'example.com', g: 'generic', p: '300x250', m: 1, pid: 'example.com/generic/300x250/1'}); + expect(r2b2.mappedParams[bid1Id]).to.deep.equal({ d: 'example.com', g: 'generic', p: '300x250', m: 1, pid: 'example.com/generic/300x250/1' }); expect(r2b2.mappedParams).to.have.property(bid2Id); - expect(r2b2.mappedParams[bid2Id]).to.deep.equal({d: 'example.com', g: 'generic', p: '300x600', m: 0, pid: 'example.com/generic/300x600/0'}); + expect(r2b2.mappedParams[bid2Id]).to.deep.equal({ d: 'example.com', g: 'generic', p: '300x600', m: 0, pid: 'example.com/generic/300x600/0' }); }); it('should pass gdpr properties', function () { const requests = spec.buildRequests(bids, bidderRequest); - const {data} = requests[0]; - const {user, regs} = data; + const { data } = requests[0]; + const { user, regs } = data; expect(user).to.be.an('object').that.has.property('ext'); expect(regs).to.be.an('object').that.has.property('ext'); expect(user.ext.consent).to.equal('consent-string'); @@ -376,21 +376,21 @@ describe('R2B2 adapter', function () { it('should pass us privacy properties', function () { const requests = spec.buildRequests(bids, bidderRequest); - const {data} = requests[0]; - const {regs} = data; + const { data } = requests[0]; + const { regs } = data; expect(regs).to.be.an('object').that.has.property('ext'); expect(regs.ext.us_privacy).to.equal('1YYY'); }); it('should pass supply chain', function () { const requests = spec.buildRequests(bids, bidderRequest); - const {data} = requests[0]; - const {source} = data; + const { data } = requests[0]; + const { source } = data; expect(source).to.be.an('object').that.has.property('ext'); expect(source.ext.schain).to.deep.equal({ complete: 1, nodes: [ - {asi: 'example.com', hp: 1, sid: '00001'} + { asi: 'example.com', hp: 1, sid: '00001' } ], ver: '1.0' }) @@ -420,7 +420,7 @@ describe('R2B2 adapter', function () { ], }, ]; - bidderRequest.ortb2 = {user: {ext: {eids: eidsArray}}} + bidderRequest.ortb2 = { user: { ext: { eids: eidsArray } } } const requests = spec.buildRequests(bids, bidderRequest); const request = requests[0]; const eids = request.data.user.ext.eids; @@ -435,9 +435,9 @@ describe('R2B2 adapter', function () { expect(result).to.be.an('array').that.has.lengthOf(0); result = spec.interpretResponse({ body: { seatbid: [] } }, {}); expect(result).to.be.an('array').that.has.lengthOf(0); - result = spec.interpretResponse({ body: { seatbid: [ {} ] } }, {}); + result = spec.interpretResponse({ body: { seatbid: [{}] } }, {}); expect(result).to.be.an('array').that.has.lengthOf(0); - result = spec.interpretResponse({ body: { seatbid: [ { bids: [] } ] } }, {}); + result = spec.interpretResponse({ body: { seatbid: [{ bids: [] }] } }, {}); expect(result).to.be.an('array').that.has.lengthOf(0); }); @@ -467,7 +467,7 @@ describe('R2B2 adapter', function () { }); it('should map ext params correctly', function() { - const dgpm = {something: 'something'}; + const dgpm = { something: 'something' }; r2b2.mappedParams = {}; r2b2.mappedParams[impId] = dgpm; const result = spec.interpretResponse({ body: serverResponse }, requestForInterpretResponse); @@ -507,7 +507,7 @@ describe('R2B2 adapter', function () { b2.w = w2; b2.h = h2; serverResponse.seatbid[0].bid.push(b2); - requestForInterpretResponse.data.imp.push({id: impId2}); + requestForInterpretResponse.data.imp.push({ id: impId2 }); const result = spec.interpretResponse({ body: serverResponse }, requestForInterpretResponse); expect(result).to.be.an('array').that.has.lengthOf(2); const firstBid = result[0]; @@ -567,7 +567,7 @@ describe('R2B2 adapter', function () { ext: { dgpm: { d: 'r2b2.cz', g: 'generic', m: 1, p: '300x300', pid: 'r2b2.cz/generic/300x300/1' } }, - params: [ { pid: 'r2b2.cz/generic/300x300/1' } ], + params: [{ pid: 'r2b2.cz/generic/300x300/1' }], }; }); afterEach(function() { diff --git a/test/spec/modules/rakutenBidAdapter_spec.js b/test/spec/modules/rakutenBidAdapter_spec.js index e6cdb12e31d..0c0d20d2a45 100644 --- a/test/spec/modules/rakutenBidAdapter_spec.js +++ b/test/spec/modules/rakutenBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai' import { spec } from 'modules/rakutenBidAdapter/index.js' import { newBidder } from 'src/adapters/bidderFactory.js' -import {config} from '../../../src/config.js'; +import { config } from '../../../src/config.js'; describe('rakutenBidAdapter', function() { const adapter = newBidder(spec); @@ -161,10 +161,10 @@ describe('rakutenBidAdapter', function() { pixelEnabled: true } }); - it('sucess usersync url', function () { + it('success usersync url', function () { const result = []; - result.push({type: 'image', url: 'https://rdn1.test/sync?uid=9876543210'}); - result.push({type: 'image', url: 'https://rdn2.test/sync?uid=9876543210'}); + result.push({ type: 'image', url: 'https://rdn1.test/sync?uid=9876543210' }); + result.push({ type: 'image', url: 'https://rdn2.test/sync?uid=9876543210' }); expect(spec.getUserSyncs(syncOptions, syncResponse)).to.deep.equal(result); }); }); diff --git a/test/spec/modules/raveltechRtdProvider_spec.js b/test/spec/modules/raveltechRtdProvider_spec.js index 051221a9248..6747eda0b4d 100644 --- a/test/spec/modules/raveltechRtdProvider_spec.js +++ b/test/spec/modules/raveltechRtdProvider_spec.js @@ -1,8 +1,8 @@ -import {hook} from '../../../src/hook.js'; -import {BANNER} from '../../../src/mediaTypes.js'; -import {raveltechSubmodule} from 'modules/raveltechRtdProvider'; +import { hook } from '../../../src/hook.js'; +import { BANNER } from '../../../src/mediaTypes.js'; +import { raveltechSubmodule } from 'modules/raveltechRtdProvider'; import adapterManager from '../../../src/adapterManager.js'; -import {registerBidder} from 'src/adapters/bidderFactory.js'; +import { registerBidder } from 'src/adapters/bidderFactory.js'; describe('raveltechRtdProvider', () => { const fakeBuildRequests = sinon.spy((valibBidRequests) => { @@ -18,7 +18,7 @@ describe('raveltechRtdProvider', () => { auctionId: 'abc', bidId: 'abc123', userIdAsEids: [ - { source: 'usersource.com', uids: [ { id: 'testid123', atype: 1 } ] } + { source: 'usersource.com', uids: [{ id: 'testid123', atype: 1 }] } ] }; @@ -37,7 +37,7 @@ describe('raveltechRtdProvider', () => { adapterManager.aliasBidAdapter('test', 'alias2'); // Init module - raveltechSubmodule.init({ params: { bidders: [ 'alias1', 'test' ], preserveOriginalBid: true } }); + raveltechSubmodule.init({ params: { bidders: ['alias1', 'test'], preserveOriginalBid: true } }); }) afterEach(() => { @@ -51,7 +51,7 @@ describe('raveltechRtdProvider', () => { auctionId: '123', bidderCode: 'alias2', bidderRequestId: 'abc', - bids: [ { ...fakeBidReq, bidder: 'alias2' } ] + bids: [{ ...fakeBidReq, bidder: 'alias2' }] }, sinon.stub(), sinon.stub(), fakeAjax, sinon.stub(), sinon.stub()); expect(fakeAjax.calledOnce).to.be.true; expect(fakeZkad.called).to.be.false; @@ -65,7 +65,7 @@ describe('raveltechRtdProvider', () => { auctionId: '123', bidderCode: 'test', bidderRequestId: 'abc', - bids: [ { ...fakeBidReq, bidder: 'test' } ] + bids: [{ ...fakeBidReq, bidder: 'test' }] }, sinon.stub(), sinon.stub(), fakeAjax, sinon.stub(), sinon.stub()); expect(fakeAjax.calledOnce).to.be.true; expect(fakeZkad.called).to.be.false; @@ -79,7 +79,7 @@ describe('raveltechRtdProvider', () => { auctionId: '123', bidderCode: 'test', bidderRequestId: 'abc', - bids: [ { ...fakeBidReq, bidder: 'test' } ] + bids: [{ ...fakeBidReq, bidder: 'test' }] }, sinon.stub(), sinon.stub(), fakeAjax, sinon.stub(), sinon.stub()); expect(fakeAjax.calledOnce).to.be.true; expect(fakeZkad.called).to.be.false; @@ -94,7 +94,7 @@ describe('raveltechRtdProvider', () => { auctionId: '123', bidderCode: 'test', bidderRequestId: 'abc', - bids: [ { ...fakeBidReq, bidder: 'test' } ] + bids: [{ ...fakeBidReq, bidder: 'test' }] }, sinon.stub(), sinon.stub(), fakeAjax, sinon.stub(), sinon.stub()); expect(fakeAjax.calledTwice).to.be.true; expect(fakeZkad.calledOnce).to.be.true; diff --git a/test/spec/modules/readpeakBidAdapter_spec.js b/test/spec/modules/readpeakBidAdapter_spec.js index 32a4d991054..8248c07014f 100644 --- a/test/spec/modules/readpeakBidAdapter_spec.js +++ b/test/spec/modules/readpeakBidAdapter_spec.js @@ -303,7 +303,7 @@ describe('ReadPeakAdapter', function() { consentString: undefined, } } - const request = spec.buildRequests([nativeBidRequest], {...bidderRequest, ...gdprData}); + const request = spec.buildRequests([nativeBidRequest], { ...bidderRequest, ...gdprData }); const data = JSON.parse(request.data); @@ -327,7 +327,7 @@ describe('ReadPeakAdapter', function() { consentString: tcString } } - const request = spec.buildRequests([nativeBidRequest], {...bidderRequest, ...gdprData}); + const request = spec.buildRequests([nativeBidRequest], { ...bidderRequest, ...gdprData }); const data = JSON.parse(request.data); @@ -465,7 +465,7 @@ describe('ReadPeakAdapter', function() { consentString: undefined, } } - const request = spec.buildRequests([bannerBidRequest], {...bidderRequest, ...gdprData}); + const request = spec.buildRequests([bannerBidRequest], { ...bidderRequest, ...gdprData }); const data = JSON.parse(request.data); @@ -489,7 +489,7 @@ describe('ReadPeakAdapter', function() { consentString: tcString } } - const request = spec.buildRequests([bannerBidRequest], {...bidderRequest, ...gdprData}); + const request = spec.buildRequests([bannerBidRequest], { ...bidderRequest, ...gdprData }); const data = JSON.parse(request.data); diff --git a/test/spec/modules/realTimeDataModule_spec.js b/test/spec/modules/realTimeDataModule_spec.js index 1e8a6d53993..ff23a1052be 100644 --- a/test/spec/modules/realTimeDataModule_spec.js +++ b/test/spec/modules/realTimeDataModule_spec.js @@ -1,14 +1,14 @@ import * as rtdModule from 'modules/rtdModule/index.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import * as sinon from 'sinon'; import { EVENTS } from '../../../src/constants.js'; import * as events from '../../../src/events.js'; import 'src/prebid.js'; -import {attachRealTimeDataProvider, onDataDeletionRequest} from 'modules/rtdModule/index.js'; -import {GDPR_GVLIDS} from '../../../src/consentHandler.js'; -import {MODULE_TYPE_RTD} from '../../../src/activities/modules.js'; -import {registerActivityControl} from '../../../src/activities/rules.js'; -import {ACTIVITY_ENRICH_UFPD, ACTIVITY_TRANSMIT_EIDS} from '../../../src/activities/activities.js'; +import { attachRealTimeDataProvider, onDataDeletionRequest } from 'modules/rtdModule/index.js'; +import { GDPR_GVLIDS } from '../../../src/consentHandler.js'; +import { MODULE_TYPE_RTD } from '../../../src/activities/modules.js'; +import { registerActivityControl } from '../../../src/activities/rules.js'; +import { ACTIVITY_ENRICH_UFPD, ACTIVITY_TRANSMIT_EIDS } from '../../../src/activities/activities.js'; describe('Real time module', function () { let eventHandlers; @@ -42,7 +42,7 @@ describe('Real time module', function () { name: 'validSM', init: () => { return true }, getTargetingData: (adUnitsCodes) => { - return {'ad2': {'key': 'validSM'}} + return { 'ad2': { 'key': 'validSM' } } }, getBidRequestData: getBidRequestDataStub }; @@ -51,7 +51,7 @@ describe('Real time module', function () { name: 'validSMWait', init: () => { return true }, getTargetingData: (adUnitsCodes) => { - return {'ad1': {'key': 'validSMWait'}} + return { 'ad1': { 'key': 'validSMWait' } } }, getBidRequestData: getBidRequestDataStub }; @@ -104,7 +104,7 @@ describe('Real time module', function () { it('are registered when RTD module is registered', () => { let mod; try { - mod = attachRealTimeDataProvider({name: 'mockRtd', gvlid: 123}); + mod = attachRealTimeDataProvider({ name: 'mockRtd', gvlid: 123 }); sinon.assert.calledWith(GDPR_GVLIDS.register, MODULE_TYPE_RTD, 'mockRtd', 123); } finally { if (mod) { @@ -124,10 +124,10 @@ describe('Real time module', function () { config.setConfig(conf); rules = [ registerActivityControl(ACTIVITY_TRANSMIT_EIDS, 'test', (params) => { - return {allow: false}; + return { allow: false }; }), registerActivityControl(ACTIVITY_ENRICH_UFPD, 'test', (params) => { - return {allow: false}; + return { allow: false }; }) ] }); @@ -143,13 +143,13 @@ describe('Real time module', function () { }); it('should be able to modify bid request', function (done) { - const request = {bidRequest: {}}; + const request = { bidRequest: {} }; getBidRequestDataStub.callsFake((req) => { req.foo = 'bar'; }); rtdModule.setBidRequestsData(() => { assert(getBidRequestDataStub.calledTwice); - assert(getBidRequestDataStub.calledWith(sinon.match({bidRequest: {}}))); + assert(getBidRequestDataStub.calledWith(sinon.match({ bidRequest: {} }))); expect(request.foo).to.eql('bar'); done(); }, request) @@ -170,7 +170,7 @@ describe('Real time module', function () { } } }; - const request = {ortb2Fragments}; + const request = { ortb2Fragments }; getBidRequestDataStub.callsFake((req) => { expect(req.ortb2Fragments.global.user.eids).to.not.exist; expect(req.ortb2Fragments.bidder.bidderA.eids).to.not.exist; @@ -197,7 +197,7 @@ describe('Real time module', function () { }, { code: 'ad2', - adserverTargeting: {preKey: 'preValue'} + adserverTargeting: { preKey: 'preValue' } } ] }; @@ -205,7 +205,7 @@ describe('Real time module', function () { const expectedAdUnits = [ { code: 'ad1', - adserverTargeting: {key: 'validSMWait'} + adserverTargeting: { key: 'validSMWait' } }, { code: 'ad2', @@ -234,7 +234,7 @@ describe('Real time module', function () { ] }; validSM.getTargetingData = (adUnits) => { - const targeting = {'module1': 'targeting'} + const targeting = { 'module1': 'targeting' } return { ad1: targeting, ad2: targeting @@ -256,7 +256,7 @@ describe('Real time module', function () { function runSetBidRequestData() { return new Promise((resolve) => { - rtdModule.setBidRequestsData(resolve, {bidRequest: {}}); + rtdModule.setBidRequestsData(resolve, { bidRequest: {} }); }); } @@ -348,7 +348,7 @@ describe('Real time module', function () { providers.forEach(p => p.getTargetingData = sinon.spy()); const auction = { adUnitCodes: ['a1'], - adUnits: [{code: 'a1'}] + adUnits: [{ code: 'a1' }] }; mockEmitEvent(EVENTS.AUCTION_END, auction); providers.forEach(p => { @@ -420,8 +420,8 @@ describe('Real time module', function () { it('calls onDataDeletionRequest on submodules', () => { const next = sinon.stub(); - onDataDeletionRequest(next, {a: 0}); - sinon.assert.calledWith(next, {a: 0}); + onDataDeletionRequest(next, { a: 0 }); + sinon.assert.calledWith(next, { a: 0 }); sinon.assert.calledWith(sm1.onDataDeletionRequest, cfg1); sinon.assert.calledWith(sm2.onDataDeletionRequest, cfg2); }); diff --git a/test/spec/modules/reconciliationRtdProvider_spec.js b/test/spec/modules/reconciliationRtdProvider_spec.js index 6efe55ddf46..d98409da518 100644 --- a/test/spec/modules/reconciliationRtdProvider_spec.js +++ b/test/spec/modules/reconciliationRtdProvider_spec.js @@ -44,14 +44,14 @@ describe('Reconciliation Real time data submodule', function () { }); it('should log error if initializied without parameters', function () { - expect(reconciliationSubmodule.init({'name': 'reconciliation', 'params': {}})).to.equal(true); + expect(reconciliationSubmodule.init({ 'name': 'reconciliation', 'params': {} })).to.equal(true); expect(utilsLogErrorSpy.calledOnce).to.be.true; }); }); describe('getData', function () { it('should return data in proper format', function () { - makeSlot({code: '/reconciliationAdunit1', divId: 'reconciliationAd1'}); + makeSlot({ code: '/reconciliationAdunit1', divId: 'reconciliationAd1' }); const targetingData = reconciliationSubmodule.getTargetingData(['/reconciliationAdunit1']); expect(targetingData['/reconciliationAdunit1'].RSDK_AUID).to.eql('/reconciliationAdunit1'); @@ -59,7 +59,7 @@ describe('Reconciliation Real time data submodule', function () { }); it('should return unit path if called with divId', function () { - makeSlot({code: '/reconciliationAdunit2', divId: 'reconciliationAd2'}); + makeSlot({ code: '/reconciliationAdunit2', divId: 'reconciliationAd2' }); const targetingData = reconciliationSubmodule.getTargetingData(['reconciliationAd2']); expect(targetingData['reconciliationAd2'].RSDK_AUID).to.eql('/reconciliationAdunit2'); @@ -67,7 +67,7 @@ describe('Reconciliation Real time data submodule', function () { }); it('should skip empty adUnit id', function () { - makeSlot({code: '/reconciliationAdunit3', divId: 'reconciliationAd3'}); + makeSlot({ code: '/reconciliationAdunit3', divId: 'reconciliationAd3' }); const targetingData = reconciliationSubmodule.getTargetingData(['reconciliationAd3', '']); expect(targetingData).to.have.all.keys('reconciliationAd3'); @@ -134,7 +134,7 @@ describe('Reconciliation Real time data submodule', function () { adSlotElement.appendChild(adSlotIframe); document.body.appendChild(adSlotElement); - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); + const adSlot = makeSlot({ code: '/reconciliationAdunit', divId: adSlotElement.id }); expect(getSlotByWin(adSlotIframe.contentWindow)).to.eql(adSlot); }); @@ -147,7 +147,7 @@ describe('Reconciliation Real time data submodule', function () { document.body.appendChild(adSlotElement); document.body.appendChild(adSlotIframe); // iframe is not in ad slot - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); + const adSlot = makeSlot({ code: '/reconciliationAdunit', divId: adSlotElement.id }); expect(getSlotByWin(adSlotIframe.contentWindow)).to.be.null; }); @@ -162,7 +162,7 @@ describe('Reconciliation Real time data submodule', function () { adSlotElement.appendChild(adSlotIframe); document.body.appendChild(adSlotElement); - const adSlot = makeSlot({code: '/reconciliationAdunit', divId: adSlotElement.id}); + const adSlot = makeSlot({ code: '/reconciliationAdunit', divId: adSlotElement.id }); // Fix targeting methods adSlot.targeting = {}; adSlot.setTargeting = function(key, value) { diff --git a/test/spec/modules/redtramBidAdapter_spec.js b/test/spec/modules/redtramBidAdapter_spec.js index 45d2b08a51f..f029a2e22a2 100644 --- a/test/spec/modules/redtramBidAdapter_spec.js +++ b/test/spec/modules/redtramBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/redtramBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/redtramBidAdapter.js'; import { BANNER } from '../../../src/mediaTypes.js'; import * as utils from '../../../src/utils.js'; diff --git a/test/spec/modules/relaidoBidAdapter_spec.js b/test/spec/modules/relaidoBidAdapter_spec.js index da3584a2de0..85ef22bbf35 100644 --- a/test/spec/modules/relaidoBidAdapter_spec.js +++ b/test/spec/modules/relaidoBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/relaidoBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/relaidoBidAdapter.js'; import * as utils from 'src/utils.js'; -import {VIDEO} from 'src/mediaTypes.js'; -import {getCoreStorageManager} from '../../../src/storageManager.js'; +import { VIDEO } from 'src/mediaTypes.js'; +import { getCoreStorageManager } from '../../../src/storageManager.js'; import * as mockGpt from '../integration/faker/googletag.js'; const UUID_KEY = 'relaido_uuid'; @@ -350,7 +350,7 @@ describe('RelaidoAdapter', function () { const data = JSON.parse(bidRequests.data); expect(data.bids).to.have.lengthOf(1); const request = data.bids[0]; - expect(request.pagekvt).to.deep.equal({testkey: ['testvalue']}); + expect(request.pagekvt).to.deep.equal({ testkey: ['testvalue'] }); }); it('should get canonicalUrl (ogUrl:true)', function () { @@ -483,7 +483,7 @@ describe('RelaidoAdapter', function () { describe('spec.getUserSyncs', function () { it('should choose iframe sync urls', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + const userSyncs = spec.getUserSyncs({ iframeEnabled: true }, [serverResponse]); expect(userSyncs).to.deep.equal([{ type: 'iframe', url: serverResponse.body.syncUrl + '?uu=hogehoge' @@ -491,7 +491,7 @@ describe('RelaidoAdapter', function () { }); it('should choose iframe sync urls if serverResponse are empty', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: true}, []); + const userSyncs = spec.getUserSyncs({ iframeEnabled: true }, []); expect(userSyncs).to.deep.equal([{ type: 'iframe', url: 'https://api.relaido.jp/tr/v1/prebid/sync.html?uu=hogehoge' @@ -500,7 +500,7 @@ describe('RelaidoAdapter', function () { it('should choose iframe sync urls if syncUrl are undefined', function () { serverResponse.body.syncUrl = undefined; - const userSyncs = spec.getUserSyncs({iframeEnabled: true}, [serverResponse]); + const userSyncs = spec.getUserSyncs({ iframeEnabled: true }, [serverResponse]); expect(userSyncs).to.deep.equal([{ type: 'iframe', url: 'https://api.relaido.jp/tr/v1/prebid/sync.html?uu=hogehoge' @@ -508,7 +508,7 @@ describe('RelaidoAdapter', function () { }); it('should return empty if iframeEnabled are false', function () { - const userSyncs = spec.getUserSyncs({iframeEnabled: false}, [serverResponse]); + const userSyncs = spec.getUserSyncs({ iframeEnabled: false }, [serverResponse]); expect(userSyncs).to.have.lengthOf(0); }); }); diff --git a/test/spec/modules/relevadRtdProvider_spec.js b/test/spec/modules/relevadRtdProvider_spec.js index 6902d910f13..2b9e84c3e11 100644 --- a/test/spec/modules/relevadRtdProvider_spec.js +++ b/test/spec/modules/relevadRtdProvider_spec.js @@ -1,9 +1,9 @@ import { addRtdData, getBidRequestData, relevadSubmodule, serverData } from 'modules/relevadRtdProvider.js'; import { server } from 'test/mocks/xhr.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import { deepClone, deepAccess, deepSetValue } from '../../../src/utils.js'; -const responseHeader = {'Content-Type': 'application/json'}; +const responseHeader = { 'Content-Type': 'application/json' }; const moduleConfigCommon = { 'dryrun': true, @@ -119,7 +119,7 @@ describe('relevadRtdProvider', function() { expect(reqBids.adUnits[0].bids[3].params || {}).to.not.have.deep.property('target', 'relevad_rtd=segment1;relevad_rtd=segment2;relevad_rtd=category3'); expect(reqBids.adUnits[0].bids[5].ortb2?.user?.ext?.data || {}).to.not.have.deep.property('segments', ['segment1', 'segment2']); expect(reqBids.adUnits[0].bids[5].ortb2?.user?.ext?.data || {}).to.not.have.deep.property('contextual_categories', ['category3']); - expect(reqBids.adUnits[0].bids[5].ortb2?.user?.ext?.data || {}).to.not.have.deep.property('contextual_categories', {'0': 'category3'}); + expect(reqBids.adUnits[0].bids[5].ortb2?.user?.ext?.data || {}).to.not.have.deep.property('contextual_categories', { '0': 'category3' }); expect(reqBids.ortb2Fragments?.bidder?.rubicon?.user?.ext?.data || {}).to.not.have.deep.property('relevad_rtd', ['segment1', 'segment2']); expect(config.getConfig('ix.firstPartyData') || {}).to.not.have.deep.property('relevad_rtd', ['segment1', 'segment2', 'category3']); }); @@ -139,7 +139,7 @@ describe('relevadRtdProvider', function() { const reqBids = { 'timeout': 10000, 'adUnits': deepClone(adUnitsCommon), - 'adUnitCodes': [ '/19968336/header-bid-tag-0' ], + 'adUnitCodes': ['/19968336/header-bid-tag-0'], 'ortb2Fragments': { 'global': { 'site': { @@ -165,7 +165,7 @@ describe('relevadRtdProvider', function() { const data = { segments: ['segment1', 'segment2'], - cats: {'category3': 100} + cats: { 'category3': 100 } }; (config.getConfig('ix') || {}).firstPartyData = null; addRtdData(reqBids, data, moduleConfig, () => {}); @@ -200,7 +200,7 @@ describe('relevadRtdProvider', function() { const data = { segments: ['segment1', 'segment2'], - cats: {'category3': 100} + cats: { 'category3': 100 } }; getBidRequestData(reqBidsConfigObj, () => {}, moduleConfig, {}); @@ -225,7 +225,7 @@ describe('Process auction end data', function() { { 'code': '/19968336/header-bid-tag-0', 'mediaTypes': { - 'banner': { 'sizes': [ [ 728, 90 ] ] } + 'banner': { 'sizes': [[728, 90]] } }, 'bids': [ { @@ -233,16 +233,16 @@ describe('Process auction end data', function() { 'params': { 'placementId': '13144370', 'keywords': { - 'relevad_rtd': [ 'IAB410-391', 'IAB63-53' ] + 'relevad_rtd': ['IAB410-391', 'IAB63-53'] } } } ], - 'ortb2Imp': { 'ext': { 'data': { 'relevad_rtd': [ 'IAB410-391', 'IAB63-53' ] }, } }, - 'sizes': [ [ 728, 90 ] ], + 'ortb2Imp': { 'ext': { 'data': { 'relevad_rtd': ['IAB410-391', 'IAB63-53'] }, } }, + 'sizes': [[728, 90]], } ], - 'adUnitCodes': [ '/19968336/header-bid-tag-0' ], + 'adUnitCodes': ['/19968336/header-bid-tag-0'], 'bidderRequests': [ { 'bidderCode': 'appnexus', @@ -261,11 +261,11 @@ describe('Process auction end data', function() { } }, 'ortb2Imp': { - 'ext': { 'data': { 'relevad_rtd': [ 'IAB410-391', 'IAB63-53' ] }, } + 'ext': { 'data': { 'relevad_rtd': ['IAB410-391', 'IAB63-53'] }, } }, - 'mediaTypes': { 'banner': { 'sizes': [ [ 728, 90 ] ] } }, + 'mediaTypes': { 'banner': { 'sizes': [[728, 90]] } }, 'adUnitCode': '/19968336/header-bid-tag-0', - 'sizes': [ [ 728, 90 ] ], + 'sizes': [[728, 90]], 'bidId': '20f0b347b07f94', 'bidderRequestId': '1d917281b2bf6c', 'auctionId': 'f7ec9895-5809-475e-8fef-49cbc221921a', @@ -278,9 +278,9 @@ describe('Process auction end data', function() { 'page': 'http://www.localhost.localdomain:8888/integrationExamples/gpt/relevadRtdProvider_example.html', 'domain': 'localhost.localdomain:8888', 'publisher': { 'domain': 'localhost.localdomain:8888' }, - 'cat': [ 'IAB410-391', 'IAB63-53' ], - 'pagecat': [ 'IAB410-391', 'IAB63-53' ], - 'sectioncat': [ 'IAB410-391', 'IAB63-53' ] + 'cat': ['IAB410-391', 'IAB63-53'], + 'pagecat': ['IAB410-391', 'IAB63-53'], + 'sectioncat': ['IAB410-391', 'IAB63-53'] }, 'device': { 'w': 326, @@ -310,7 +310,7 @@ describe('Process auction end data', function() { 'reachedTop': true, 'isAmp': false, 'numIframes': 0, - 'stack': [ 'http://www.localhost.localdomain:8888/integrationExamples/gpt/relevadRtdProvider_example.html' ], + 'stack': ['http://www.localhost.localdomain:8888/integrationExamples/gpt/relevadRtdProvider_example.html'], 'referer': 'http://www.localhost.localdomain:8888/integrationExamples/gpt/relevadRtdProvider_example.html', 'canonicalUrl': null } @@ -320,9 +320,9 @@ describe('Process auction end data', function() { 'page': 'http://www.localhost.localdomain:8888/integrationExamples/gpt/relevadRtdProvider_example.html', 'domain': 'localhost.localdomain:8888', 'publisher': { 'domain': 'localhost.localdomain:8888' }, - 'cat': [ 'IAB410-391', 'IAB63-53' ], - 'pagecat': [ 'IAB410-391', 'IAB63-53' ], - 'sectioncat': [ 'IAB410-391', 'IAB63-53' ] + 'cat': ['IAB410-391', 'IAB63-53'], + 'pagecat': ['IAB410-391', 'IAB63-53'], + 'sectioncat': ['IAB410-391', 'IAB63-53'] }, 'device': { 'w': 326, diff --git a/test/spec/modules/relevantdigitalBidAdapter_spec.js b/test/spec/modules/relevantdigitalBidAdapter_spec.js index 45a84d5991d..ee9bea32ad3 100644 --- a/test/spec/modules/relevantdigitalBidAdapter_spec.js +++ b/test/spec/modules/relevantdigitalBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {spec, resetBidderConfigs} from 'modules/relevantdigitalBidAdapter.js'; +import { spec, resetBidderConfigs } from 'modules/relevantdigitalBidAdapter.js'; import { parseUrl } from 'src/utils.js'; const expect = require('chai').expect; @@ -228,7 +228,7 @@ const resetAndBuildRequest = (params) => { describe('Relevant Digital Bid Adaper', function () { describe('buildRequests', () => { const [request] = resetAndBuildRequest(); - const {data, url} = request + const { data, url } = request it('should give the correct URL', () => { expect(url).equal(`https://${PBS_HOST}/openrtb2/auction`); }); @@ -292,7 +292,7 @@ describe('Relevant Digital Bid Adaper', function () { const responseSyncs = BID_RESPONSE.ext.relevant.sync; const allSyncs = spec.getUserSyncs({ pixelEnabled: true }, [{ body: BID_RESPONSE }], null, null); it('should return one sync object per pixel', () => { - const expectedResult = responseSyncs.map(({ url }) => ({url, type: 'image'})); + const expectedResult = responseSyncs.map(({ url }) => ({ url, type: 'image' })); expect(allSyncs).to.deep.equal(expectedResult) }); }); diff --git a/test/spec/modules/resetdigitalBidAdapter_spec.js b/test/spec/modules/resetdigitalBidAdapter_spec.js index d010ee86556..0cc2663fdbc 100644 --- a/test/spec/modules/resetdigitalBidAdapter_spec.js +++ b/test/spec/modules/resetdigitalBidAdapter_spec.js @@ -82,7 +82,7 @@ describe('resetdigitalBidAdapter', function () { }) describe('buildRequests', function () { - const req = spec.buildRequests([ bannerRequest ], { refererInfo: { } }) + const req = spec.buildRequests([bannerRequest], { refererInfo: { } }) let rdata it('should return request object', function () { diff --git a/test/spec/modules/retailspotBidAdapter_spec.js b/test/spec/modules/retailspotBidAdapter_spec.js index 7e693c7973d..eba905c54d2 100644 --- a/test/spec/modules/retailspotBidAdapter_spec.js +++ b/test/spec/modules/retailspotBidAdapter_spec.js @@ -18,8 +18,8 @@ describe('RetailSpot Adapter', function () { consentString: consentString, gdprApplies: true }, - refererInfo: {location: referrerUrl, canonicalUrl, domain, topmostLocation: 'fakePageURL'}, - ortb2: {site: {page: pageUrl, ref: referrerUrl}} + refererInfo: { location: referrerUrl, canonicalUrl, domain, topmostLocation: 'fakePageURL' }, + ortb2: { site: { page: pageUrl, ref: referrerUrl } } }; const bidRequestWithSinglePlacement = [ @@ -83,9 +83,9 @@ describe('RetailSpot Adapter', function () { }, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } + { + 'banner': + { 'sizes': ['300x250'] } }, 'transactionId': 'bid_id_0_transaction_id' } @@ -101,9 +101,9 @@ describe('RetailSpot Adapter', function () { }, 'sizes': '300x250', 'mediaTypes': - { 'banner': - {'sizes': ['300x250'] - } + { + 'banner': + { 'sizes': ['300x250'] } }, 'transactionId': 'bid_id_0_transaction_id' }, @@ -116,9 +116,9 @@ describe('RetailSpot Adapter', function () { }, 'sizes': [[300, 600]], 'mediaTypes': - { 'banner': - {'sizes': ['300x600'] - } + { + 'banner': + { 'sizes': ['300x600'] } }, 'transactionId': 'bid_id_1_transaction_id' }, @@ -388,7 +388,7 @@ describe('RetailSpot Adapter', function () { it('receive reponse with single placement', function () { serverResponse.body = responseWithSinglePlacement; - const result = spec.interpretResponse(serverResponse, {data: '{"bids":' + JSON.stringify(requestDataOnePlacement) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"bids":' + JSON.stringify(requestDataOnePlacement) + '}' }); expect(result.length).to.equal(1); expect(result[0].cpm).to.equal(0.5); @@ -400,7 +400,7 @@ describe('RetailSpot Adapter', function () { it('receive reponse with multiple placement', function () { serverResponse.body = responseWithMultiplePlacements; - const result = spec.interpretResponse(serverResponse, {data: '{"bids":' + JSON.stringify(requestDataMultiPlacement) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"bids":' + JSON.stringify(requestDataMultiPlacement) + '}' }); expect(result.length).to.equal(2); @@ -417,7 +417,7 @@ describe('RetailSpot Adapter', function () { it('receive Vast reponse with Video ad', function () { serverResponse.body = responseWithSingleVideo; - const result = spec.interpretResponse(serverResponse, {data: '{"bids":' + JSON.stringify(sentBidVideo) + '}'}); + const result = spec.interpretResponse(serverResponse, { data: '{"bids":' + JSON.stringify(sentBidVideo) + '}' }); expect(result.length).to.equal(1); expect(result).to.deep.equal(videoResult); diff --git a/test/spec/modules/revantageBidAdapter_spec.js b/test/spec/modules/revantageBidAdapter_spec.js new file mode 100644 index 00000000000..b560c218bfd --- /dev/null +++ b/test/spec/modules/revantageBidAdapter_spec.js @@ -0,0 +1,994 @@ +import { expect } from 'chai'; +import sinon from 'sinon'; +import { spec } from '../../../modules/revantageBidAdapter.js'; +import { newBidder } from '../../../src/adapters/bidderFactory.js'; +import { deepClone } from '../../../src/utils.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import * as utils from '../../../src/utils.js'; + +const ENDPOINT_URL = 'https://bid.revantage.io/bid'; +const SYNC_URL = 'https://sync.revantage.io/sync'; + +describe('RevantageBidAdapter', function () { + const adapter = newBidder(spec); + + describe('inherited functions', function () { + it('exists and is a function', function () { + expect(adapter.callBids).to.exist.and.to.be.a('function'); + }); + }); + + describe('isBidRequestValid', function () { + const validBid = { + bidder: 'revantage', + params: { + feedId: 'test-feed-123' + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 600]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + }; + + it('should return true when required params found', function () { + expect(spec.isBidRequestValid(validBid)).to.equal(true); + }); + + it('should return false when bid is undefined', function () { + expect(spec.isBidRequestValid(undefined)).to.equal(false); + }); + + it('should return false when bid is null', function () { + expect(spec.isBidRequestValid(null)).to.equal(false); + }); + + it('should return false when params is missing', function () { + const invalidBid = deepClone(validBid); + delete invalidBid.params; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); + }); + + it('should return false when feedId is missing', function () { + const invalidBid = deepClone(validBid); + invalidBid.params = {}; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); + }); + + it('should return false when feedId is empty string', function () { + const invalidBid = deepClone(validBid); + invalidBid.params = { feedId: '' }; + expect(spec.isBidRequestValid(invalidBid)).to.equal(false); + }); + + it('should return true with optional params', function () { + const bidWithOptional = deepClone(validBid); + bidWithOptional.params.placementId = 'test-placement'; + bidWithOptional.params.publisherId = 'test-publisher'; + expect(spec.isBidRequestValid(bidWithOptional)).to.equal(true); + }); + }); + + describe('buildRequests', function () { + const validBidRequests = [{ + bidder: 'revantage', + params: { + feedId: 'test-feed-123', + placementId: 'test-placement', + publisherId: 'test-publisher' + }, + adUnitCode: 'adunit-code', + sizes: [[300, 250], [300, 600]], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + banner: { + sizes: [[300, 250], [300, 600]] + } + }, + getFloor: function(params) { + return { + currency: 'USD', + floor: 0.5 + }; + } + }]; + + const bidderRequest = { + auctionId: '1d1a030790a475', + bidderRequestId: '22edbae2733bf6', + timeout: 3000, + gdprConsent: { + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==', + gdprApplies: true + }, + uspConsent: '1---', + gppConsent: { + gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', + applicableSections: [7, 8] + }, + ortb2: { + site: { + domain: 'example.com', + page: 'https://example.com/test' + }, + device: { + ua: 'Mozilla/5.0...', + language: 'en' + } + } + }; + + it('should return valid request object', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + + expect(request).to.be.an('object'); + expect(request.method).to.equal('POST'); + expect(request.url).to.include(ENDPOINT_URL); + expect(request.url).to.include('feed=test-feed-123'); + expect(request.options.contentType).to.equal('text/plain'); + expect(request.options.withCredentials).to.equal(false); + expect(request.bidRequests).to.equal(validBidRequests); + }); + + it('should include all required OpenRTB fields', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.id).to.equal('1d1a030790a475'); + expect(data.imp).to.be.an('array').with.lengthOf(1); + expect(data.site).to.be.an('object'); + expect(data.device).to.be.an('object'); + expect(data.user).to.be.an('object'); + expect(data.regs).to.be.an('object'); + expect(data.cur).to.deep.equal(['USD']); + expect(data.tmax).to.equal(3000); + }); + + it('should build correct impression object', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + const imp = data.imp[0]; + + expect(imp.id).to.equal('30b31c1838de1e'); + expect(imp.tagid).to.equal('adunit-code'); + expect(imp.bidfloor).to.equal(0.5); + expect(imp.banner).to.be.an('object'); + expect(imp.banner.w).to.equal(300); + expect(imp.banner.h).to.equal(250); + expect(imp.banner.format).to.deep.equal([ + { w: 300, h: 250 }, + { w: 300, h: 600 } + ]); + }); + + it('should include bidder-specific ext parameters', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + const imp = data.imp[0]; + + expect(imp.ext.feedId).to.equal('test-feed-123'); + expect(imp.ext.bidder.placementId).to.equal('test-placement'); + expect(imp.ext.bidder.publisherId).to.equal('test-publisher'); + }); + + it('should include GDPR consent data', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.regs.ext.gdpr).to.equal(1); + expect(data.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); + }); + + it('should include CCPA/USP consent', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.regs.ext.us_privacy).to.equal('1---'); + }); + + it('should include GPP consent with sections as array', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.regs.ext.gpp).to.equal('DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA'); + expect(data.regs.ext.gpp_sid).to.deep.equal([7, 8]); + }); + + it('should handle GDPR not applies', function () { + const bidderRequestNoGdpr = deepClone(bidderRequest); + bidderRequestNoGdpr.gdprConsent.gdprApplies = false; + + const request = spec.buildRequests(validBidRequests, bidderRequestNoGdpr); + const data = JSON.parse(request.data); + + expect(data.regs.ext.gdpr).to.equal(0); + }); + + it('should handle missing getFloor function', function () { + const bidRequestsWithoutFloor = deepClone(validBidRequests); + delete bidRequestsWithoutFloor[0].getFloor; + + const request = spec.buildRequests(bidRequestsWithoutFloor, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.imp[0].bidfloor).to.equal(0); + }); + + it('should handle getFloor returning non-USD currency', function () { + const bidRequestsEurFloor = deepClone(validBidRequests); + bidRequestsEurFloor[0].getFloor = function() { + return { currency: 'EUR', floor: 0.5 }; + }; + + const request = spec.buildRequests(bidRequestsEurFloor, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.imp[0].bidfloor).to.equal(0); + }); + + it('should handle missing ortb2 data', function () { + const bidderRequestNoOrtb2 = deepClone(bidderRequest); + delete bidderRequestNoOrtb2.ortb2; + + const request = spec.buildRequests(validBidRequests, bidderRequestNoOrtb2); + const data = JSON.parse(request.data); + + expect(data.site).to.be.an('object'); + expect(data.site.domain).to.exist; + expect(data.device).to.be.an('object'); + }); + + it('should include supply chain when present in bidderRequest', function () { + const bidderRequestWithSchain = deepClone(bidderRequest); + bidderRequestWithSchain.schain = { + ver: '1.0', + complete: 1, + nodes: [{ + asi: 'example.com', + sid: '12345', + hp: 1 + }] + }; + + const request = spec.buildRequests(validBidRequests, bidderRequestWithSchain); + const data = JSON.parse(request.data); + + expect(data.schain).to.exist; + expect(data.schain.ver).to.equal('1.0'); + expect(data.schain.complete).to.equal(1); + expect(data.schain.nodes).to.have.lengthOf(1); + }); + + it('should include supply chain from first bid request', function () { + const bidRequestsWithSchain = deepClone(validBidRequests); + bidRequestsWithSchain[0].schain = { + ver: '1.0', + complete: 1, + nodes: [{ asi: 'bidder.com', sid: '999', hp: 1 }] + }; + + const bidderRequestNoSchain = deepClone(bidderRequest); + delete bidderRequestNoSchain.schain; + + const request = spec.buildRequests(bidRequestsWithSchain, bidderRequestNoSchain); + const data = JSON.parse(request.data); + + expect(data.schain).to.exist; + expect(data.schain.nodes[0].asi).to.equal('bidder.com'); + }); + + it('should include user EIDs when present', function () { + const bidRequestsWithEids = deepClone(validBidRequests); + bidRequestsWithEids[0].userIdAsEids = [ + { + source: 'id5-sync.com', + uids: [{ id: 'test-id5-id', atype: 1 }] + } + ]; + + const request = spec.buildRequests(bidRequestsWithEids, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.user.eids).to.be.an('array'); + expect(data.user.eids[0].source).to.equal('id5-sync.com'); + }); + + it('should return empty array when feedIds differ across bids', function () { + const mixedFeedBidRequests = [ + { + bidder: 'revantage', + params: { feedId: 'feed-1' }, + adUnitCode: 'adunit-1', + mediaTypes: { banner: { sizes: [[300, 250]] } }, + sizes: [[300, 250]], + bidId: 'bid1', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + }, + { + bidder: 'revantage', + params: { feedId: 'feed-2' }, + adUnitCode: 'adunit-2', + mediaTypes: { banner: { sizes: [[728, 90]] } }, + sizes: [[728, 90]], + bidId: 'bid2', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + } + ]; + + const request = spec.buildRequests(mixedFeedBidRequests, bidderRequest); + expect(request).to.deep.equal([]); + }); + + it('should return empty array on exception', function () { + const request = spec.buildRequests(null, bidderRequest); + expect(request).to.deep.equal([]); + }); + + it('should handle video media type', function () { + const videoBidRequests = [{ + bidder: 'revantage', + params: { feedId: 'test-feed-123' }, + adUnitCode: 'video-adunit', + bidId: 'video-bid-1', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + video: { + playerSize: [[640, 480]], + mimes: ['video/mp4', 'video/webm'], + protocols: [2, 3, 5, 6], + api: [1, 2], + placement: 1, + minduration: 5, + maxduration: 30, + skip: 1, + skipmin: 5, + skipafter: 5 + } + } + }]; + + const request = spec.buildRequests(videoBidRequests, bidderRequest); + const data = JSON.parse(request.data); + const imp = data.imp[0]; + + expect(imp.video).to.exist; + expect(imp.video.w).to.equal(640); + expect(imp.video.h).to.equal(480); + expect(imp.video.mimes).to.deep.equal(['video/mp4', 'video/webm']); + expect(imp.video.protocols).to.deep.equal([2, 3, 5, 6]); + expect(imp.video.minduration).to.equal(5); + expect(imp.video.maxduration).to.equal(30); + expect(imp.video.skip).to.equal(1); + expect(imp.banner).to.be.undefined; + }); + + it('should handle multi-format (banner + video) bid', function () { + const multiFormatBidRequests = [{ + bidder: 'revantage', + params: { feedId: 'test-feed-123' }, + adUnitCode: 'multi-format-adunit', + bidId: 'multi-bid-1', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475', + mediaTypes: { + banner: { + sizes: [[300, 250]] + }, + video: { + playerSize: [[640, 480]], + mimes: ['video/mp4'] + } + } + }]; + + const request = spec.buildRequests(multiFormatBidRequests, bidderRequest); + const data = JSON.parse(request.data); + const imp = data.imp[0]; + + expect(imp.banner).to.exist; + expect(imp.video).to.exist; + }); + + it('should handle multiple impressions with same feedId', function () { + const multipleBidRequests = [ + { + bidder: 'revantage', + params: { feedId: 'test-feed-123' }, + adUnitCode: 'adunit-1', + mediaTypes: { banner: { sizes: [[300, 250]] } }, + sizes: [[300, 250]], + bidId: 'bid1', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + }, + { + bidder: 'revantage', + params: { feedId: 'test-feed-123' }, + adUnitCode: 'adunit-2', + mediaTypes: { banner: { sizes: [[728, 90]] } }, + sizes: [[728, 90]], + bidId: 'bid2', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + } + ]; + + const request = spec.buildRequests(multipleBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.imp).to.have.lengthOf(2); + expect(data.imp[0].id).to.equal('bid1'); + expect(data.imp[1].id).to.equal('bid2'); + }); + + it('should use default sizes when sizes array is empty', function () { + const bidWithEmptySizes = [{ + bidder: 'revantage', + params: { feedId: 'test-feed' }, + adUnitCode: 'adunit-code', + mediaTypes: { banner: { sizes: [] } }, + sizes: [], + bidId: '30b31c1838de1e', + bidderRequestId: '22edbae2733bf6', + auctionId: '1d1a030790a475' + }]; + + const request = spec.buildRequests(bidWithEmptySizes, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.imp[0].banner.w).to.equal(300); + expect(data.imp[0].banner.h).to.equal(250); + }); + + it('should include prebid version in ext', function () { + const request = spec.buildRequests(validBidRequests, bidderRequest); + const data = JSON.parse(request.data); + + expect(data.ext).to.exist; + expect(data.ext.prebid).to.exist; + expect(data.ext.prebid.version).to.exist; + }); + }); + + describe('interpretResponse', function () { + const serverResponse = { + body: { + id: '1d1a030790a475', + seatbid: [{ + seat: 'test-dsp', + bid: [{ + id: 'test-bid-id', + impid: '30b31c1838de1e', + price: 1.25, + crid: 'test-creative-123', + adm: '
Test Ad Markup
', + w: 300, + h: 250, + adomain: ['advertiser.com'], + dealid: 'deal-123' + }] + }], + cur: 'USD' + } + }; + + const bidRequest = { + bidRequests: [{ + bidId: '30b31c1838de1e', + adUnitCode: 'adunit-code', + mediaTypes: { + banner: { + sizes: [[300, 250]] + } + } + }] + }; + + it('should return valid banner bid response', function () { + const result = spec.interpretResponse(serverResponse, bidRequest); + + expect(result).to.be.an('array').with.lengthOf(1); + + const bid = result[0]; + expect(bid.requestId).to.equal('30b31c1838de1e'); + expect(bid.cpm).to.equal(1.25); + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + expect(bid.creativeId).to.equal('test-creative-123'); + expect(bid.currency).to.equal('USD'); + expect(bid.netRevenue).to.equal(true); + expect(bid.ttl).to.equal(300); + expect(bid.ad).to.equal('
Test Ad Markup
'); + expect(bid.mediaType).to.equal(BANNER); + expect(bid.dealId).to.equal('deal-123'); + }); + + it('should include meta data in bid response', function () { + const result = spec.interpretResponse(serverResponse, bidRequest); + const bid = result[0]; + + expect(bid.meta).to.be.an('object'); + expect(bid.meta.advertiserDomains).to.deep.equal(['advertiser.com']); + expect(bid.meta.dsp).to.equal('test-dsp'); + expect(bid.meta.networkName).to.equal('Revantage'); + }); + + it('should include burl when provided', function () { + const responseWithBurl = deepClone(serverResponse); + responseWithBurl.body.seatbid[0].bid[0].burl = 'https://bid.revantage.io/win?auction=1d1a030790a475&dsp=test-dsp&price=0.625000&impid=30b31c1838de1e&bidid=test-bid-id&adid=test-creative-123&page=&domain=&country=&feedid=test-feed&ref='; + + const result = spec.interpretResponse(responseWithBurl, bidRequest); + const bid = result[0]; + + expect(bid.burl).to.include('https://bid.revantage.io/win'); + expect(bid.burl).to.include('dsp=test-dsp'); + expect(bid.burl).to.include('impid=30b31c1838de1e'); + }); + + it('should handle video response with vastXml', function () { + const videoResponse = deepClone(serverResponse); + videoResponse.body.seatbid[0].bid[0].vastXml = '...'; + delete videoResponse.body.seatbid[0].bid[0].adm; + + const videoBidRequest = { + bidRequests: [{ + bidId: '30b31c1838de1e', + adUnitCode: 'video-adunit', + mediaTypes: { + video: { + playerSize: [[640, 480]] + } + } + }] + }; + + const result = spec.interpretResponse(videoResponse, videoBidRequest); + const bid = result[0]; + + expect(bid.mediaType).to.equal(VIDEO); + expect(bid.vastXml).to.equal('...'); + }); + + it('should handle video response with vastUrl', function () { + const videoResponse = deepClone(serverResponse); + videoResponse.body.seatbid[0].bid[0].vastUrl = 'https://vast.example.com/vast.xml'; + delete videoResponse.body.seatbid[0].bid[0].adm; + + const videoBidRequest = { + bidRequests: [{ + bidId: '30b31c1838de1e', + adUnitCode: 'video-adunit', + mediaTypes: { + video: { + playerSize: [[640, 480]] + } + } + }] + }; + + const result = spec.interpretResponse(videoResponse, videoBidRequest); + const bid = result[0]; + + expect(bid.mediaType).to.equal(VIDEO); + expect(bid.vastUrl).to.equal('https://vast.example.com/vast.xml'); + }); + + it('should detect video from ext.mediaType', function () { + const videoResponse = deepClone(serverResponse); + videoResponse.body.seatbid[0].bid[0].adm = '...'; + videoResponse.body.seatbid[0].bid[0].ext = { mediaType: 'video' }; + + const result = spec.interpretResponse(videoResponse, bidRequest); + const bid = result[0]; + + expect(bid.mediaType).to.equal(VIDEO); + expect(bid.vastXml).to.equal('...'); + }); + + it('should use default dimensions from bid request when missing in response', function () { + const responseNoDimensions = deepClone(serverResponse); + delete responseNoDimensions.body.seatbid[0].bid[0].w; + delete responseNoDimensions.body.seatbid[0].bid[0].h; + + const result = spec.interpretResponse(responseNoDimensions, bidRequest); + const bid = result[0]; + + expect(bid.width).to.equal(300); + expect(bid.height).to.equal(250); + }); + + it('should include dspPrice from ext when available', function () { + const responseWithDspPrice = deepClone(serverResponse); + responseWithDspPrice.body.seatbid[0].bid[0].ext = { dspPrice: 1.50 }; + + const result = spec.interpretResponse(responseWithDspPrice, bidRequest); + const bid = result[0]; + + expect(bid.meta.dspPrice).to.equal(1.50); + }); + + it('should return empty array for null response body', function () { + const result = spec.interpretResponse({ body: null }, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should return empty array for undefined response body', function () { + const result = spec.interpretResponse({}, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should return empty array when seatbid is not an array', function () { + const invalidResponse = { + body: { + id: '1d1a030790a475', + seatbid: 'not-an-array', + cur: 'USD' + } + }; + + const result = spec.interpretResponse(invalidResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should return empty array for empty seatbid', function () { + const emptyResponse = { + body: { + id: '1d1a030790a475', + seatbid: [], + cur: 'USD' + } + }; + + const result = spec.interpretResponse(emptyResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should filter out bids with zero price', function () { + const zeroPriceResponse = deepClone(serverResponse); + zeroPriceResponse.body.seatbid[0].bid[0].price = 0; + + const result = spec.interpretResponse(zeroPriceResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should filter out bids with negative price', function () { + const negativePriceResponse = deepClone(serverResponse); + negativePriceResponse.body.seatbid[0].bid[0].price = -1; + + const result = spec.interpretResponse(negativePriceResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should filter out bids without ad markup', function () { + const noAdmResponse = deepClone(serverResponse); + delete noAdmResponse.body.seatbid[0].bid[0].adm; + + const result = spec.interpretResponse(noAdmResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should filter out bids with unknown impid', function () { + const unknownImpidResponse = deepClone(serverResponse); + unknownImpidResponse.body.seatbid[0].bid[0].impid = 'unknown-imp-id'; + + const result = spec.interpretResponse(unknownImpidResponse, bidRequest); + expect(result).to.deep.equal([]); + }); + + it('should handle missing bidRequests in request object', function () { + const result = spec.interpretResponse(serverResponse, {}); + expect(result).to.deep.equal([]); + }); + + it('should handle multiple seatbids', function () { + const multiSeatResponse = deepClone(serverResponse); + multiSeatResponse.body.seatbid.push({ + seat: 'another-dsp', + bid: [{ + id: 'another-bid-id', + impid: 'another-imp-id', + price: 2.00, + crid: 'another-creative', + adm: '
Another Ad
', + w: 728, + h: 90, + adomain: ['another-advertiser.com'] + }] + }); + + const multiBidRequest = { + bidRequests: [ + { + bidId: '30b31c1838de1e', + adUnitCode: 'adunit-code', + mediaTypes: { banner: { sizes: [[300, 250]] } } + }, + { + bidId: 'another-imp-id', + adUnitCode: 'adunit-code-2', + mediaTypes: { banner: { sizes: [[728, 90]] } } + } + ] + }; + + const result = spec.interpretResponse(multiSeatResponse, multiBidRequest); + + expect(result).to.have.lengthOf(2); + expect(result[0].meta.dsp).to.equal('test-dsp'); + expect(result[1].meta.dsp).to.equal('another-dsp'); + }); + + it('should use default currency USD when not specified', function () { + const noCurrencyResponse = deepClone(serverResponse); + delete noCurrencyResponse.body.cur; + + const result = spec.interpretResponse(noCurrencyResponse, bidRequest); + const bid = result[0]; + + expect(bid.currency).to.equal('USD'); + }); + + it('should generate creativeId when crid is missing', function () { + const noCridResponse = deepClone(serverResponse); + delete noCridResponse.body.seatbid[0].bid[0].crid; + + const result = spec.interpretResponse(noCridResponse, bidRequest); + const bid = result[0]; + + expect(bid.creativeId).to.exist; + expect(bid.creativeId).to.satisfy(crid => + crid === 'test-bid-id' || crid.startsWith('revantage-') + ); + }); + + it('should handle empty adomain array', function () { + const noAdomainResponse = deepClone(serverResponse); + delete noAdomainResponse.body.seatbid[0].bid[0].adomain; + + const result = spec.interpretResponse(noAdomainResponse, bidRequest); + const bid = result[0]; + + expect(bid.meta.advertiserDomains).to.deep.equal([]); + }); + + it('should use "unknown" for missing seat', function () { + const noSeatResponse = deepClone(serverResponse); + delete noSeatResponse.body.seatbid[0].seat; + + const result = spec.interpretResponse(noSeatResponse, bidRequest); + const bid = result[0]; + + expect(bid.meta.dsp).to.equal('unknown'); + }); + }); + + describe('getUserSyncs', function () { + const syncOptions = { + iframeEnabled: true, + pixelEnabled: true + }; + + const gdprConsent = { + gdprApplies: true, + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==' + }; + + const uspConsent = '1---'; + + const gppConsent = { + gppString: 'DBACNYA~CPXxRfAPXxRfAAfKABENB-CgAAAAAAAAAAYgAAAAAAAA', + applicableSections: [7, 8] + }; + + it('should return iframe sync when iframe enabled', function () { + const syncs = spec.getUserSyncs( + { iframeEnabled: true, pixelEnabled: false }, + [], + gdprConsent, + uspConsent, + gppConsent + ); + + expect(syncs).to.be.an('array').with.lengthOf(1); + expect(syncs[0].type).to.equal('iframe'); + expect(syncs[0].url).to.include(SYNC_URL); + }); + + it('should return pixel sync when pixel enabled', function () { + const syncs = spec.getUserSyncs( + { iframeEnabled: false, pixelEnabled: true }, + [], + gdprConsent, + uspConsent, + gppConsent + ); + + expect(syncs).to.be.an('array').with.lengthOf(1); + expect(syncs[0].type).to.equal('image'); + expect(syncs[0].url).to.include(SYNC_URL); + expect(syncs[0].url).to.include('tag=img'); + }); + + it('should return both syncs when both enabled', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs).to.have.lengthOf(2); + expect(syncs.map(s => s.type)).to.include('iframe'); + expect(syncs.map(s => s.type)).to.include('image'); + }); + + it('should include cache buster parameter', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('cb='); + }); + + it('should include GDPR parameters when consent applies', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('gdpr=1'); + expect(syncs[0].url).to.include('gdpr_consent=BOJ%2FP2HOJ%2FP2HABABMAAAAAZ%2BA%3D%3D'); + }); + + it('should set gdpr=0 when GDPR does not apply', function () { + const gdprNotApplies = { + gdprApplies: false, + consentString: 'BOJ/P2HOJ/P2HABABMAAAAAZ+A==' + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprNotApplies, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('gdpr=0'); + }); + + it('should include USP consent parameter', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('us_privacy=1---'); + }); + + it('should include GPP parameters', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs[0].url).to.include('gpp='); + expect(syncs[0].url).to.include('gpp_sid=7%2C8'); + }); + + it('should handle missing GDPR consent', function () { + const syncs = spec.getUserSyncs(syncOptions, [], null, uspConsent, gppConsent); + + expect(syncs[0].url).to.not.include('gdpr='); + expect(syncs[0].url).to.not.include('gdpr_consent='); + }); + + it('should handle missing USP consent', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, null, gppConsent); + + expect(syncs[0].url).to.not.include('us_privacy='); + }); + + it('should handle missing GPP consent', function () { + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, null); + + expect(syncs[0].url).to.not.include('gpp='); + expect(syncs[0].url).to.not.include('gpp_sid='); + }); + + it('should handle undefined GPP string', function () { + const partialGppConsent = { + applicableSections: [7, 8] + }; + + const syncs = spec.getUserSyncs(syncOptions, [], gdprConsent, uspConsent, partialGppConsent); + + expect(syncs[0].url).to.not.include('gpp='); + expect(syncs[0].url).to.include('gpp_sid=7%2C8'); + }); + + it('should return empty array when no sync options enabled', function () { + const syncs = spec.getUserSyncs( + { iframeEnabled: false, pixelEnabled: false }, + [], + gdprConsent, + uspConsent, + gppConsent + ); + + expect(syncs).to.be.an('array').that.is.empty; + }); + + it('should return empty array when syncOptions is empty object', function () { + const syncs = spec.getUserSyncs({}, [], gdprConsent, uspConsent, gppConsent); + + expect(syncs).to.be.an('array').that.is.empty; + }); + }); + + describe('onBidWon', function () { + let triggerPixelStub; + + beforeEach(function () { + triggerPixelStub = sinon.stub(utils, 'triggerPixel'); + }); + + afterEach(function () { + triggerPixelStub.restore(); + }); + + it('should call triggerPixel with correct burl', function () { + const bid = { + bidId: '30b31c1838de1e', + cpm: 1.25, + adUnitCode: 'adunit-code', + burl: 'https://bid.revantage.io/win?auction=1d1a030790a475&dsp=test-dsp&price=0.625000&impid=30b31c1838de1e&bidid=test-bid-id&adid=test-ad-123&page=https%3A%2F%2Fexample.com&domain=example.com&country=US&feedid=test-feed&ref=' + }; + + spec.onBidWon(bid); + + expect(triggerPixelStub.calledOnce).to.be.true; + expect(triggerPixelStub.firstCall.args[0]).to.include('https://bid.revantage.io/win'); + expect(triggerPixelStub.firstCall.args[0]).to.include('dsp=test-dsp'); + expect(triggerPixelStub.firstCall.args[0]).to.include('impid=30b31c1838de1e'); + expect(triggerPixelStub.firstCall.args[0]).to.include('feedid=test-feed'); + }); + + it('should not throw error when burl is missing', function () { + const bid = { + bidId: '30b31c1838de1e', + cpm: 1.25, + adUnitCode: 'adunit-code' + }; + + expect(() => spec.onBidWon(bid)).to.not.throw(); + expect(triggerPixelStub.called).to.be.false; + }); + + it('should handle burl with all query parameters', function () { + // This is the actual format generated by your RTB server + const burl = 'https://bid.revantage.io/win?' + + 'auction=auction_123456789' + + '&dsp=Improve_Digital' + + '&price=0.750000' + + '&impid=imp_001%7Cfeed123' + // URL encoded pipe for feedId in impid + '&bidid=bid_abc' + + '&adid=creative_xyz' + + '&page=https%3A%2F%2Fexample.com%2Fpage' + + '&domain=example.com' + + '&country=US' + + '&feedid=feed123' + + '&ref=https%3A%2F%2Fgoogle.com'; + + const bid = { + bidId: 'imp_001', + cpm: 1.50, + burl: burl + }; + + spec.onBidWon(bid); + + expect(triggerPixelStub.calledOnce).to.be.true; + const calledUrl = triggerPixelStub.firstCall.args[0]; + expect(calledUrl).to.include('auction=auction_123456789'); + expect(calledUrl).to.include('dsp=Improve_Digital'); + expect(calledUrl).to.include('price=0.750000'); + expect(calledUrl).to.include('domain=example.com'); + expect(calledUrl).to.include('country=US'); + expect(calledUrl).to.include('feedid=feed123'); + }); + }); + + describe('spec properties', function () { + it('should have correct bidder code', function () { + expect(spec.code).to.equal('revantage'); + }); + + it('should support banner and video media types', function () { + expect(spec.supportedMediaTypes).to.deep.equal([BANNER, VIDEO]); + }); + }); +}); diff --git a/test/spec/modules/revcontentBidAdapter_spec.js b/test/spec/modules/revcontentBidAdapter_spec.js index 6d660d1b3b5..7a5da3c7b1d 100644 --- a/test/spec/modules/revcontentBidAdapter_spec.js +++ b/test/spec/modules/revcontentBidAdapter_spec.js @@ -1,6 +1,6 @@ // jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {spec} from 'modules/revcontentBidAdapter.js'; +import { assert, expect } from 'chai'; +import { spec } from 'modules/revcontentBidAdapter.js'; import { NATIVE } from 'src/mediaTypes.js'; import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; @@ -14,7 +14,7 @@ describe('revcontent adapter', function () { bidder: 'revcontent', nativeParams: {}, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', @@ -38,18 +38,18 @@ describe('revcontent adapter', function () { bidder: 'revcontent', nativeParams: {}, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, widgetId: 33861, endpoint: 'trends-s0.revcontent.com' } }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}}); + let request = spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }); request = request[0]; assert.equal(request.method, 'POST'); assert.equal(request.url, 'https://trends-s0.revcontent.com/rtb?apiKey=8a33fa9cf220ae685dcc3544f847cdda858d3b1c&userId=673&widgetId=33861'); - assert.deepEqual(request.options, {contentType: 'application/json'}); + assert.deepEqual(request.options, { contentType: 'application/json' }); assert.ok(request.data); }); @@ -59,14 +59,14 @@ describe('revcontent adapter', function () { bidder: 'revcontent', nativeParams: {}, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', endpoint: 'trends-s0.revcontent.com' } }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}}); + let request = spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }); request = request[0]; const data = Object.keys(request); @@ -79,7 +79,7 @@ describe('revcontent adapter', function () { bidder: 'revcontent', nativeParams: {}, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', @@ -87,7 +87,7 @@ describe('revcontent adapter', function () { bidfloor: 0.05 } }]; - let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}}); + let request = spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }); request = JSON.parse(request[0].data); assert.equal(request.imp[0].bidfloor, 0.05); assert.equal(request.device.ua, navigator.userAgent); @@ -98,7 +98,7 @@ describe('revcontent adapter', function () { bidder: 'revcontent', nativeParams: {}, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', @@ -112,7 +112,7 @@ describe('revcontent adapter', function () { currency: 'USD' }; }; - let request = spec.buildRequests(validBidRequests, {refererInfo: {page: 'page'}}); + let request = spec.buildRequests(validBidRequests, { refererInfo: { page: 'page' } }); request = JSON.parse(request[0].data); assert.equal(request.imp[0].bidfloor, 0.07); assert.equal(request.device.ua, navigator.userAgent); @@ -139,22 +139,22 @@ describe('revcontent adapter', function () { } }, params: { - size: {width: 300, height: 250}, + size: { width: 300, height: 250 }, apiKey: '8a33fa9cf220ae685dcc3544f847cdda858d3b1c', userId: 673, domain: 'test.com', endpoint: 'trends-s0.revcontent.com' } }]; - const refererInfo = {page: 'page'}; - let request = spec.buildRequests(validBidRequests, {refererInfo}); + const refererInfo = { page: 'page' }; + let request = spec.buildRequests(validBidRequests, { refererInfo }); request = JSON.parse(request[0].data); assert.equal(request.imp[0].bidfloor, 0.1); assert.deepEqual(request.site, { domain: 'test.com', page: 'page', - publisher: {id: 673, domain: 'test.com'} + publisher: { id: 673, domain: 'test.com' } }); }); }); @@ -320,13 +320,13 @@ describe('revcontent adapter', function () { body: { id: null, bidid: null, - seatbid: [{bid: []}], + seatbid: [{ bid: [] }], cur: 'USD' } }; const bidRequest = { data: '{}', - bids: [{bidId: 'bidId1'}] + bids: [{ bidId: 'bidId1' }] }; const result = spec.interpretResponse(serverResponse, bidRequest)[0]; assert.ok(!result); diff --git a/test/spec/modules/revnewBidAdapter_spec.js b/test/spec/modules/revnewBidAdapter_spec.js index 904b59589cb..765a467386f 100644 --- a/test/spec/modules/revnewBidAdapter_spec.js +++ b/test/spec/modules/revnewBidAdapter_spec.js @@ -605,7 +605,7 @@ describe('Revnew bid adapter tests', () => { }); it('Verifies user sync with cookies in bid response', () => { response.body.ext = { - cookies: [{'type': 'image', 'url': 'http://www.cookie.sync.org/'}] + cookies: [{ 'type': 'image', 'url': 'http://www.cookie.sync.org/' }] }; const syncs = spec.getUserSyncs({}, [response], DEFAULT_OPTIONS.gdprConsent); const expectedSyncs = [{ type: 'image', url: 'http://www.cookie.sync.org/' }]; diff --git a/test/spec/modules/rewardedInterestIdSystem_spec.js b/test/spec/modules/rewardedInterestIdSystem_spec.js index b6ce1e03f76..8301944999d 100644 --- a/test/spec/modules/rewardedInterestIdSystem_spec.js +++ b/test/spec/modules/rewardedInterestIdSystem_spec.js @@ -1,8 +1,8 @@ import sinon from 'sinon'; -import {expect} from 'chai'; +import { expect } from 'chai'; import * as utils from 'src/utils.js'; -import {attachIdSystem} from 'modules/userId'; -import {createEidsArray} from 'modules/userId/eids'; +import { attachIdSystem } from 'modules/userId'; +import { createEidsArray } from 'modules/userId/eids'; import { MODULE_NAME, SOURCE, @@ -121,7 +121,7 @@ describe('rewardedInterestIdSystem', () => { it('API is set before getId, getIdentityToken return error', async () => { const error = Error(); - window.__riApi = {getIdentityToken: () => Promise.reject(error)}; + window.__riApi = { getIdentityToken: () => Promise.reject(error) }; const idResponse = rewardedInterestIdSubmodule.getId(); idResponse.callback(callbackSpy); await window.__riApi.getIdentityToken().catch(() => {}); @@ -134,7 +134,7 @@ describe('rewardedInterestIdSystem', () => { mockReadySate = 'loading'; const idResponse = rewardedInterestIdSubmodule.getId(); idResponse.callback(callbackSpy); - window.__riApi = {getIdentityToken: () => Promise.reject(error)}; + window.__riApi = { getIdentityToken: () => Promise.reject(error) }; await window.__riApi.getIdentityToken().catch(() => {}); expect(callbackSpy.calledOnceWithExactly()).to.be.true; expect(logErrorSpy.calledOnceWithExactly(errorIdFetch, error)).to.be.true; diff --git a/test/spec/modules/rhythmoneBidAdapter_spec.js b/test/spec/modules/rhythmoneBidAdapter_spec.js index b9fa0cd37af..862b56f6e82 100644 --- a/test/spec/modules/rhythmoneBidAdapter_spec.js +++ b/test/spec/modules/rhythmoneBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {spec} from '../../../modules/rhythmoneBidAdapter.js'; +import { spec } from '../../../modules/rhythmoneBidAdapter.js'; import * as utils from '../../../src/utils.js'; import * as dnt from 'libraries/dnt/index.js'; import * as sinon from 'sinon'; @@ -398,7 +398,7 @@ describe('rhythmone adapter tests', function () { 'path': 'mypath' }, 'mediaTypes': { - 'banner': {'sizes': [['400', '500'], ['4n0', '5g0']]} + 'banner': { 'sizes': [['400', '500'], ['4n0', '5g0']] } }, 'adUnitCode': 'div-gpt-ad-1438287399331-0', 'transactionId': 'd7b773de-ceaa-484d-89ca-d9f51b8d61ec', diff --git a/test/spec/modules/richaudienceBidAdapter_spec.js b/test/spec/modules/richaudienceBidAdapter_spec.js index fb90c793188..2c7ba990ebc 100644 --- a/test/spec/modules/richaudienceBidAdapter_spec.js +++ b/test/spec/modules/richaudienceBidAdapter_spec.js @@ -1,9 +1,9 @@ // import or require modules necessary for the test, e.g.: -import {expect} from 'chai'; // may prefer 'assert' in place of 'expect' +import { expect } from 'chai'; // may prefer 'assert' in place of 'expect' import { spec } from 'modules/richaudienceBidAdapter.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import sinon from 'sinon'; @@ -378,7 +378,7 @@ describe('Richaudience adapter tests', function () { it('Referer undefined', function () { config.setConfig({ - 'currency': {'adServerCurrency': 'USD'} + 'currency': { 'adServerCurrency': 'USD' } }) const request = spec.buildRequests(DEFAULT_PARAMS_NEW_SIZES, { @@ -724,7 +724,7 @@ describe('Richaudience adapter tests', function () { it('Verifies bidder aliases', function () { expect(spec.aliases).to.have.lengthOf(1); - expect(spec.aliases[0]).to.deep.equal({code: 'ra', gvlid: 108}); + expect(spec.aliases[0]).to.deep.equal({ code: 'ra', gvlid: 108 }); }); it('Verifies bidder gvlid', function () { @@ -940,7 +940,7 @@ describe('Richaudience adapter tests', function () { }); it('Verifies user syncs iframe include', function () { config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'include'}}} + 'userSync': { filterSettings: { iframe: { bidders: '*', filter: 'include' } } } }) var syncs = spec.getUserSyncs({ @@ -971,17 +971,17 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(1); syncs = spec.getUserSyncs({ iframeEnabled: false, - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); it('Verifies user syncs iframe exclude', function () { config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'exclude'}}} + 'userSync': { filterSettings: { iframe: { bidders: '*', filter: 'exclude' } } } }) var syncs = spec.getUserSyncs({ @@ -1011,18 +1011,18 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(0); syncs = spec.getUserSyncs({ iframeEnabled: false, - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); it('Verifies user syncs image include', function () { config.setConfig({ - 'userSync': {filterSettings: {image: {bidders: '*', filter: 'include'}}} + 'userSync': { filterSettings: { image: { bidders: '*', filter: 'include' } } } }) var syncs = spec.getUserSyncs({ @@ -1061,7 +1061,7 @@ describe('Richaudience adapter tests', function () { it('Verifies user syncs image exclude', function () { config.setConfig({ - 'userSync': {filterSettings: {image: {bidders: '*', filter: 'exclude'}}} + 'userSync': { filterSettings: { image: { bidders: '*', filter: 'exclude' } } } }) var syncs = spec.getUserSyncs({ @@ -1099,8 +1099,8 @@ describe('Richaudience adapter tests', function () { config.setConfig({ 'userSync': { filterSettings: { - iframe: {bidders: '*', filter: 'include'}, - image: {bidders: '*', filter: 'include'} + iframe: { bidders: '*', filter: 'include' }, + image: { bidders: '*', filter: 'include' } } } }) @@ -1137,13 +1137,13 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(1); syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); @@ -1151,8 +1151,8 @@ describe('Richaudience adapter tests', function () { config.setConfig({ 'userSync': { filterSettings: { - iframe: {bidders: '*', filter: 'exclude'}, - image: {bidders: '*', filter: 'exclude'} + iframe: { bidders: '*', filter: 'exclude' }, + image: { bidders: '*', filter: 'exclude' } } } }) @@ -1188,13 +1188,13 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(0); syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); @@ -1202,8 +1202,8 @@ describe('Richaudience adapter tests', function () { config.setConfig({ 'userSync': { filterSettings: { - iframe: {bidders: '*', filter: 'exclude'}, - image: {bidders: '*', filter: 'include'} + iframe: { bidders: '*', filter: 'exclude' }, + image: { bidders: '*', filter: 'include' } } } }) @@ -1240,13 +1240,13 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(1); syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); @@ -1254,8 +1254,8 @@ describe('Richaudience adapter tests', function () { config.setConfig({ 'userSync': { filterSettings: { - iframe: {bidders: '*', filter: 'include'}, - image: {bidders: '*', filter: 'exclude'} + iframe: { bidders: '*', filter: 'include' }, + image: { bidders: '*', filter: 'exclude' } } } }) @@ -1292,22 +1292,22 @@ describe('Richaudience adapter tests', function () { syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true - }, [], {consentString: '', gdprApplies: false}); + }, [], { consentString: '', gdprApplies: false }); expect(syncs).to.have.lengthOf(1); syncs = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false - }, [], {consentString: '', gdprApplies: true}); + }, [], { consentString: '', gdprApplies: true }); expect(syncs).to.have.lengthOf(0); }); it('Verifies user syncs iframe/image include with GPP', function () { config.setConfig({ - 'userSync': {filterSettings: {iframe: {bidders: '*', filter: 'include'}}} + 'userSync': { filterSettings: { iframe: { bidders: '*', filter: 'include' } } } }) - let syncs = spec.getUserSyncs({iframeEnabled: true}, [BID_RESPONSE], { + let syncs = spec.getUserSyncs({ iframeEnabled: true }, [BID_RESPONSE], { gppString: 'DBABL~BVVqAAEABgA.QA', applicableSections: [7] }, @@ -1316,10 +1316,10 @@ describe('Richaudience adapter tests', function () { expect(syncs[0].type).to.equal('iframe'); config.setConfig({ - 'userSync': {filterSettings: {image: {bidders: '*', filter: 'include'}}} + 'userSync': { filterSettings: { image: { bidders: '*', filter: 'include' } } } }) - syncs = spec.getUserSyncs({pixelEnabled: true}, [BID_RESPONSE], { + syncs = spec.getUserSyncs({ pixelEnabled: true }, [BID_RESPONSE], { gppString: 'DBABL~BVVqAAEABgA.QA', applicableSections: [7, 5] }, @@ -1333,7 +1333,7 @@ describe('Richaudience adapter tests', function () { gppString: 'DBACMYA~CP5P4cAP5P4cAPoABAESAlEAAAAAAAAAAAAAA2QAQA2ADZABADYAAAAA.QA2QAQA2AAAA.IA2QAQA2AAAA~BP5P4cAP5P4cAPoABABGBACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA', applicableSections: [0] }; - const result = spec.getUserSyncs({pixelEnabled: true}, undefined, undefined, undefined, gppConsent); + const result = spec.getUserSyncs({ pixelEnabled: true }, undefined, undefined, undefined, gppConsent); expect(result).to.deep.equal([{ type: 'image', url: `https://sync.richaudience.com/bf7c142f4339da0278e83698a02b0854/?referrer=http%3A%2F%2Fdomain.com&gpp=DBACMYA~CP5P4cAP5P4cAPoABAESAlEAAAAAAAAAAAAAA2QAQA2ADZABADYAAAAA.QA2QAQA2AAAA.IA2QAQA2AAAA~BP5P4cAP5P4cAPoABABGBACAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA&gpp_sid=0` diff --git a/test/spec/modules/riseBidAdapter_spec.js b/test/spec/modules/riseBidAdapter_spec.js index bc7446a448c..9a9941f17cf 100644 --- a/test/spec/modules/riseBidAdapter_spec.js +++ b/test/spec/modules/riseBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/riseBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; import * as utils from 'src/utils.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; const ENDPOINT = 'https://hb.yellowblue.io/hb-multi'; const TEST_ENDPOINT = 'https://hb.yellowblue.io/hb-multi-test'; @@ -104,7 +104,7 @@ describe('riseAdapter', function () { 'mediaTypes': { 'banner': { 'sizes': [ - [ 300, 250 ] + [300, 250] ] }, 'video': { @@ -163,7 +163,7 @@ describe('riseAdapter', function () { const bidderRequest = { bidderCode: 'rise', - ortb2: {device: {}}, + ortb2: { device: {} }, } const placementId = '12345678'; const api = [1, 2]; @@ -348,7 +348,7 @@ describe('riseAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -361,7 +361,7 @@ describe('riseAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -369,7 +369,7 @@ describe('riseAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); @@ -377,7 +377,7 @@ describe('riseAdapter', function () { }); it('should not send the gpp param if gppConsent is false in the bidRequest', function () { - const bidderRequestWithoutGPP = Object.assign({gppConsent: false}, bidderRequest); + const bidderRequestWithoutGPP = Object.assign({ gppConsent: false }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithoutGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gpp'); @@ -385,7 +385,7 @@ describe('riseAdapter', function () { }); it('should send the gpp param if gppConsent is true in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: {gppString: 'gpp-consent', applicableSections: [7]}}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: { gppString: 'gpp-consent', applicableSections: [7] } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); console.log('request.data.params'); console.log(request.data.params); @@ -448,15 +448,15 @@ describe('riseAdapter', function () { 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -470,20 +470,20 @@ describe('riseAdapter', function () { 'sua': { 'platform': { 'brand': 'macOS', - 'version': [ '12', '4', '0' ] + 'version': ['12', '4', '0'] }, 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -514,7 +514,7 @@ describe('riseAdapter', function () { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }, }; diff --git a/test/spec/modules/rivrAnalyticsAdapter_spec.js b/test/spec/modules/rivrAnalyticsAdapter_spec.js index 1192d1ba604..fef07af2376 100644 --- a/test/spec/modules/rivrAnalyticsAdapter_spec.js +++ b/test/spec/modules/rivrAnalyticsAdapter_spec.js @@ -13,9 +13,10 @@ import analyticsAdapter, { getCookie, storeAndReturnRivrUsrIdCookie, arrayDifference, - activelyWaitForBannersToRender} from 'modules/rivrAnalyticsAdapter.js'; + activelyWaitForBannersToRender +} from 'modules/rivrAnalyticsAdapter.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; import adapterManager from 'src/adapterManager.js'; import * as ajax from 'src/ajax.js'; import { EVENTS } from 'src/constants.js'; diff --git a/test/spec/modules/robustAppsBidAdapter_spec.js b/test/spec/modules/robustAppsBidAdapter_spec.js index 931d50023f6..237706548a8 100644 --- a/test/spec/modules/robustAppsBidAdapter_spec.js +++ b/test/spec/modules/robustAppsBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {config} from 'src/config.js'; -import {spec} from 'modules/robustAppsBidAdapter.js'; -import {deepClone} from 'src/utils'; -import {getBidFloor} from '../../../libraries/xeUtils/bidderUtils.js'; +import { expect } from 'chai'; +import { config } from 'src/config.js'; +import { spec } from 'modules/robustAppsBidAdapter.js'; +import { deepClone } from 'src/utils'; +import { getBidFloor } from '../../../libraries/xeUtils/bidderUtils.js'; const ENDPOINT = 'https://pbjs.rbstsystems.live'; @@ -48,12 +48,12 @@ defaultRequestVideo.mediaTypes = { const videoBidderRequest = { bidderCode: 'robustApps', - bids: [{mediaTypes: {video: {}}, bidId: 'qwerty'}] + bids: [{ mediaTypes: { video: {} }, bidId: 'qwerty' }] }; const displayBidderRequest = { bidderCode: 'robustApps', - bids: [{bidId: 'qwerty'}] + bids: [{ bidId: 'qwerty' }] }; describe('robustAppsBidAdapter', () => { @@ -103,7 +103,7 @@ describe('robustAppsBidAdapter', () => { expect(request).to.have.property('tz').and.to.equal(new Date().getTimezoneOffset()); expect(request).to.have.property('bc').and.to.equal(1); expect(request).to.have.property('floor').and.to.equal(null); - expect(request).to.have.property('banner').and.to.deep.equal({sizes: [[300, 250], [300, 200]]}); + expect(request).to.have.property('banner').and.to.deep.equal({ sizes: [[300, 250], [300, 200]] }); expect(request).to.have.property('gdprConsent').and.to.deep.equal({}); expect(request).to.have.property('userEids').and.to.deep.equal([]); expect(request).to.have.property('usPrivacy').and.to.equal(''); @@ -195,7 +195,7 @@ describe('robustAppsBidAdapter', () => { it('should build request with valid bidfloor', function () { const bfRequest = deepClone(defaultRequest); - bfRequest.getFloor = () => ({floor: 5, currency: 'USD'}); + bfRequest.getFloor = () => ({ floor: 5, currency: 'USD' }); const request = JSON.parse(spec.buildRequests([bfRequest], {}).data)[0]; expect(request).to.have.property('floor').and.to.equal(5); }); @@ -211,8 +211,8 @@ describe('robustAppsBidAdapter', () => { it('should build request with extended ids', function () { const idRequest = deepClone(defaultRequest); idRequest.userIdAsEids = [ - {source: 'adserver.org', uids: [{id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: {rtiPartner: 'TDID'}}]}, - {source: 'pubcid.org', uids: [{id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1}]} + { source: 'adserver.org', uids: [{ id: 'TTD_ID_FROM_USER_ID_MODULE', atype: 1, ext: { rtiPartner: 'TDID' } }] }, + { source: 'pubcid.org', uids: [{ id: 'pubCommonId_FROM_USER_ID_MODULE', atype: 1 }] } ]; const request = JSON.parse(spec.buildRequests([idRequest], {}).data)[0]; expect(request).to.have.property('userEids').and.deep.equal(idRequest.userIdAsEids); @@ -264,7 +264,7 @@ describe('robustAppsBidAdapter', () => { } }; - const validResponse = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponse = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponse[0]; expect(validResponse).to.be.an('array').that.is.not.empty; expect(bid.requestId).to.equal('qwerty'); @@ -273,7 +273,7 @@ describe('robustAppsBidAdapter', () => { expect(bid.width).to.equal(300); expect(bid.height).to.equal(250); expect(bid.ttl).to.equal(600); - expect(bid.meta).to.deep.equal({advertiserDomains: ['robustApps']}); + expect(bid.meta).to.deep.equal({ advertiserDomains: ['robustApps'] }); }); it('should interpret valid banner response', function () { @@ -294,7 +294,7 @@ describe('robustAppsBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: displayBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: displayBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('banner'); @@ -320,7 +320,7 @@ describe('robustAppsBidAdapter', () => { } }; - const validResponseBanner = spec.interpretResponse(serverResponse, {bidderRequest: videoBidderRequest}); + const validResponseBanner = spec.interpretResponse(serverResponse, { bidderRequest: videoBidderRequest }); const bid = validResponseBanner[0]; expect(validResponseBanner).to.be.an('array').that.is.not.empty; expect(bid.mediaType).to.equal('video'); @@ -336,12 +336,12 @@ describe('robustAppsBidAdapter', () => { }); it('should return empty if sync is not allowed', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('should allow iframe sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [{ body: { data: [{ requestId: 'qwerty', @@ -360,7 +360,7 @@ describe('robustAppsBidAdapter', () => { }); it('should allow pixel sync', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -379,7 +379,7 @@ describe('robustAppsBidAdapter', () => { }); it('should allow pixel sync and parse consent params', function () { - const opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [{ + const opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [{ body: { data: [{ requestId: 'qwerty', @@ -403,20 +403,20 @@ describe('robustAppsBidAdapter', () => { describe('getBidFloor', function () { it('should return null when getFloor is not a function', () => { - const bid = {getFloor: 2}; + const bid = { getFloor: 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when getFloor doesnt return an object', () => { - const bid = {getFloor: () => 2}; + const bid = { getFloor: () => 2 }; const result = getBidFloor(bid); expect(result).to.be.null; }); it('should return null when floor is not a number', () => { const bid = { - getFloor: () => ({floor: 'string', currency: 'USD'}) + getFloor: () => ({ floor: 'string', currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -424,7 +424,7 @@ describe('robustAppsBidAdapter', () => { it('should return null when currency is not USD', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'EUR'}) + getFloor: () => ({ floor: 5, currency: 'EUR' }) }; const result = getBidFloor(bid); expect(result).to.be.null; @@ -432,7 +432,7 @@ describe('robustAppsBidAdapter', () => { it('should return floor value when everything is correct', () => { const bid = { - getFloor: () => ({floor: 5, currency: 'USD'}) + getFloor: () => ({ floor: 5, currency: 'USD' }) }; const result = getBidFloor(bid); expect(result).to.equal(5); diff --git a/test/spec/modules/rocketlabBidAdapter_spec.js b/test/spec/modules/rocketlabBidAdapter_spec.js index fc162c67959..ffe48e4c2d9 100644 --- a/test/spec/modules/rocketlabBidAdapter_spec.js +++ b/test/spec/modules/rocketlabBidAdapter_spec.js @@ -544,7 +544,7 @@ describe("RocketLabBidAdapter", function () { consentString: "ALL", gdprApplies: true, }, - {} + undefined ); expect(syncData).to.be.an("array").which.is.not.empty; expect(syncData[0]).to.be.an("object"); @@ -560,9 +560,7 @@ describe("RocketLabBidAdapter", function () { {}, {}, {}, - { - consentString: "1---", - } + "1---" ); expect(syncData).to.be.an("array").which.is.not.empty; expect(syncData[0]).to.be.an("object"); @@ -578,7 +576,7 @@ describe("RocketLabBidAdapter", function () { {}, {}, {}, - {}, + undefined, { gppString: "abc123", applicableSections: [8], diff --git a/test/spec/modules/roxotAnalyticsAdapter_spec.js b/test/spec/modules/roxotAnalyticsAdapter_spec.js index 4882d6e7c63..6c57bd6b031 100644 --- a/test/spec/modules/roxotAnalyticsAdapter_spec.js +++ b/test/spec/modules/roxotAnalyticsAdapter_spec.js @@ -1,6 +1,6 @@ import roxotAnalytic from 'modules/roxotAnalyticsAdapter.js'; -import {expect} from 'chai'; -import {server} from 'test/mocks/xhr.js'; +import { expect } from 'chai'; +import { server } from 'test/mocks/xhr.js'; import { EVENTS } from 'src/constants.js'; const events = require('src/events'); @@ -179,7 +179,7 @@ describe('Roxot Prebid Analytic', function () { expect(server.requests.length).to.equal(1); expect(server.requests[0].url).to.equal('https://' + roxotConfigServerUrl + '/c?publisherId=' + publisherId + '&host=localhost'); - server.requests[0].respond(200, {'Content-Type': 'application/json'}, '{"a": 1, "i": 1, "bat": 1}'); + server.requests[0].respond(200, { 'Content-Type': 'application/json' }, '{"a": 1, "i": 1, "bat": 1}'); events.emit(EVENTS.AUCTION_INIT, auctionInit); events.emit(EVENTS.BID_REQUESTED, bidRequested); @@ -258,7 +258,7 @@ describe('Roxot Prebid Analytic', function () { expect(server.requests.length).to.equal(1); expect(server.requests[0].url).to.equal('https://' + roxotConfigServerUrl + '/c?publisherId=' + publisherId + '&host=localhost'); - server.requests[0].respond(200, {'Content-Type': 'application/json'}, '{"a": 1, "i": 1, "bat": 1}'); + server.requests[0].respond(200, { 'Content-Type': 'application/json' }, '{"a": 1, "i": 1, "bat": 1}'); events.emit(EVENTS.AUCTION_INIT, auctionInit); events.emit(EVENTS.BID_REQUESTED, bidRequested); @@ -410,7 +410,7 @@ describe('Roxot Prebid Analytic', function () { server.requests[0].respond(500); - expect(roxotAnalytic.getOptions().serverConfig).to.deep.equal({a: 1, i: 1, bat: 1, isError: 1}); + expect(roxotAnalytic.getOptions().serverConfig).to.deep.equal({ a: 1, i: 1, bat: 1, isError: 1 }); }); }); diff --git a/test/spec/modules/rtbhouseBidAdapter_spec.js b/test/spec/modules/rtbhouseBidAdapter_spec.js index e75190037bd..000ed9a2d56 100644 --- a/test/spec/modules/rtbhouseBidAdapter_spec.js +++ b/test/spec/modules/rtbhouseBidAdapter_spec.js @@ -346,7 +346,7 @@ describe('RTBHouseAdapter', () => { it('should include bidfloor from floor module if available', () => { const bidRequest = Object.assign([], bidRequests); - bidRequest[0].getFloor = () => ({floor: 1.22, currency: 'USD'}); + bidRequest[0].getFloor = () => ({ floor: 1.22, currency: 'USD' }); const request = spec.buildRequests(bidRequest, bidderRequest); const data = JSON.parse(request.data); expect(data.imp[0].bidfloor).to.equal(1.22) @@ -354,7 +354,7 @@ describe('RTBHouseAdapter', () => { it('should use bidfloor from floor module if both floor module and bid floor available', () => { const bidRequest = Object.assign([], bidRequests); - bidRequest[0].getFloor = () => ({floor: 1.22, currency: 'USD'}); + bidRequest[0].getFloor = () => ({ floor: 1.22, currency: 'USD' }); bidRequest[0].params.bidfloor = 0.01; const request = spec.buildRequests(bidRequest, bidderRequest); const data = JSON.parse(request.data); @@ -448,9 +448,9 @@ describe('RTBHouseAdapter', () => { const data = JSON.parse(request.data); expect(data.bcat).to.deep.equal(localBidderRequest.ortb2.bcat); expect(data.badv).to.deep.equal(localBidderRequest.ortb2.badv); - expect(data.site).to.nested.include({'ext.data': 'some site data'}); - expect(data.device).to.nested.include({'ext.data': 'some device data'}); - expect(data.user).to.nested.include({'ext.data': 'some user data'}); + expect(data.site).to.nested.include({ 'ext.data': 'some site data' }); + expect(data.device).to.nested.include({ 'ext.data': 'some device data' }); + expect(data.user).to.nested.include({ 'ext.data': 'some user data' }); }); context('DSA', () => { @@ -816,14 +816,14 @@ describe('RTBHouseAdapter', () => { } ]; let bidderRequest; - const result = spec.interpretResponse({body: response}, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); }); it('handles nobid responses', function () { const response = ''; let bidderRequest; - const result = spec.interpretResponse({body: response}, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(result.length).to.equal(0); }); @@ -862,7 +862,7 @@ describe('RTBHouseAdapter', () => { } ]; let bidderRequest; - const result = spec.interpretResponse({body: response}, {bidderRequest}); + const result = spec.interpretResponse({ body: response }, { bidderRequest }); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); expect(result[0]).to.have.nested.property('meta.dsa'); @@ -918,7 +918,7 @@ describe('RTBHouseAdapter', () => { }]; it('should contain native assets in valid format', () => { - const bids = spec.interpretResponse({body: response}, {}); + const bids = spec.interpretResponse({ body: response }, {}); expect(bids[0].meta.advertiserDomains).to.deep.equal(['rtbhouse.com']); expect(bids[0].native).to.deep.equal({ title: 'Title text', diff --git a/test/spec/modules/rtbsapeBidAdapter_spec.js b/test/spec/modules/rtbsapeBidAdapter_spec.js index 538a728d03a..57861994c93 100644 --- a/test/spec/modules/rtbsapeBidAdapter_spec.js +++ b/test/spec/modules/rtbsapeBidAdapter_spec.js @@ -1,19 +1,19 @@ -import {expect} from 'chai'; -import {spec} from 'modules/rtbsapeBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/rtbsapeBidAdapter.js'; import 'src/prebid.js'; import * as utils from 'src/utils.js'; -import {executeRenderer, Renderer} from 'src/Renderer.js'; +import { executeRenderer, Renderer } from 'src/Renderer.js'; describe('rtbsapeBidAdapterTests', function () { describe('isBidRequestValid', function () { it('valid', function () { - expect(spec.isBidRequestValid({bidder: 'rtbsape', mediaTypes: {banner: true}, params: {placeId: 4321}})).to.equal(true); - expect(spec.isBidRequestValid({bidder: 'rtbsape', mediaTypes: {video: true}, params: {placeId: 4321}})).to.equal(true); + expect(spec.isBidRequestValid({ bidder: 'rtbsape', mediaTypes: { banner: true }, params: { placeId: 4321 } })).to.equal(true); + expect(spec.isBidRequestValid({ bidder: 'rtbsape', mediaTypes: { video: true }, params: { placeId: 4321 } })).to.equal(true); }); it('invalid', function () { - expect(spec.isBidRequestValid({bidder: 'rtbsape', mediaTypes: {banner: true}, params: {}})).to.equal(false); - expect(spec.isBidRequestValid({bidder: 'rtbsape', params: {placeId: 4321}})).to.equal(false); + expect(spec.isBidRequestValid({ bidder: 'rtbsape', mediaTypes: { banner: true }, params: {} })).to.equal(false); + expect(spec.isBidRequestValid({ bidder: 'rtbsape', params: { placeId: 4321 } })).to.equal(false); }); }); @@ -21,7 +21,7 @@ describe('rtbsapeBidAdapterTests', function () { const bidRequestData = [{ bidId: 'bid1234', bidder: 'rtbsape', - params: {placeId: 4321}, + params: { placeId: 4321 }, sizes: [[240, 400]] }]; const bidderRequest = { @@ -54,7 +54,7 @@ describe('rtbsapeBidAdapterTests', function () { }] } }; - const bids = spec.interpretResponse(serverResponse, {data: {bids: [{mediaTypes: {banner: true}}]}}); + const bids = spec.interpretResponse(serverResponse, { data: { bids: [{ mediaTypes: { banner: true } }] } }); expect(bids).to.have.lengthOf(1); const bid = bids[0]; expect(bid.cpm).to.equal(2.21); @@ -123,7 +123,7 @@ describe('rtbsapeBidAdapterTests', function () { let spy = false; window.sapeRtbPlayerHandler = function (id, w, h, m) { - const player = {addSlot: () => [id, w, h, m]} + const player = { addSlot: () => [id, w, h, m] } expect(spy).to.equal(false); spy = sinon.spy(player, 'addSlot'); return player; @@ -168,7 +168,7 @@ describe('rtbsapeBidAdapterTests', function () { }] } }; - const bids = spec.interpretResponse(serverResponse, {data: {bids: [{mediaTypes: {banner: true}}]}}); + const bids = spec.interpretResponse(serverResponse, { data: { bids: [{ mediaTypes: { banner: true } }] } }); expect(bids).to.have.lengthOf(1); const bid = bids[0]; expect(bid.cpm).to.equal(2.23); @@ -182,9 +182,9 @@ describe('rtbsapeBidAdapterTests', function () { }); it('getUserSyncs', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); expect(syncs).to.be.an('array').that.to.have.lengthOf(1); - expect(syncs[0]).to.deep.equal({type: 'iframe', url: 'https://www.acint.net/mc/?dp=141'}); + expect(syncs[0]).to.deep.equal({ type: 'iframe', url: 'https://www.acint.net/mc/?dp=141' }); }); describe('onBidWon', function () { @@ -197,12 +197,12 @@ describe('rtbsapeBidAdapterTests', function () { }); it('called once', function () { - spec.onBidWon({cpm: '2.21', nurl: 'https://ssp-rtb.sape.ru/track?event=win'}); + spec.onBidWon({ cpm: '2.21', nurl: 'https://ssp-rtb.sape.ru/track?event=win' }); expect(utils.triggerPixel.calledOnce).to.equal(true); }); it('called false', function () { - spec.onBidWon({cpm: '2.21'}); + spec.onBidWon({ cpm: '2.21' }); expect(utils.triggerPixel.called).to.equal(false); }); }); diff --git a/test/spec/modules/rubiconBidAdapter_spec.js b/test/spec/modules/rubiconBidAdapter_spec.js index bd9990f75de..3b58568dd87 100644 --- a/test/spec/modules/rubiconBidAdapter_spec.js +++ b/test/spec/modules/rubiconBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec, getPriceGranularity, @@ -8,7 +8,7 @@ import { resetImpIdMap, converter } from 'modules/rubiconBidAdapter.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; @@ -16,9 +16,9 @@ import 'modules/userId/index.js'; import 'modules/priceFloors.js'; import 'modules/multibid/index.js'; import adapterManager from 'src/adapterManager.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; import { deepClone } from '../../../src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const INTEGRATION = `pbjs_lite_v$prebid.version$`; // $prebid.version$ will be substituted in by gulp in built prebid const PBS_INTEGRATION = 'pbjs'; @@ -252,7 +252,7 @@ describe('the rubicon adapter', function () { 'size_id': 201, }; bid.userId = { - lipb: {lipbid: '0000-1111-2222-3333', segments: ['segA', 'segB']}, + lipb: { lipbid: '0000-1111-2222-3333', segments: ['segA', 'segB'] }, idl_env: '1111-2222-3333-4444', tdid: '3000', pubcid: '4000', @@ -347,7 +347,7 @@ describe('the rubicon adapter', function () { ] } ]; - bidderRequest.ortb2 = {user: {ext: {eids}}}; + bidderRequest.ortb2 = { user: { ext: { eids } } }; return bidderRequest; } @@ -455,19 +455,19 @@ describe('the rubicon adapter', function () { }; sizeMap = [ - {sizeId: 1, size: '468x60'}, - {sizeId: 2, size: '728x90'}, - {sizeId: 5, size: '120x90'}, - {sizeId: 8, size: '120x600'}, - {sizeId: 9, size: '160x600'}, - {sizeId: 10, size: '300x600'}, - {sizeId: 13, size: '200x200'}, - {sizeId: 14, size: '250x250'}, - {sizeId: 15, size: '300x250'}, - {sizeId: 16, size: '336x280'}, - {sizeId: 19, size: '300x100'}, - {sizeId: 31, size: '980x120'}, - {sizeId: 32, size: '250x360'} + { sizeId: 1, size: '468x60' }, + { sizeId: 2, size: '728x90' }, + { sizeId: 5, size: '120x90' }, + { sizeId: 8, size: '120x600' }, + { sizeId: 9, size: '160x600' }, + { sizeId: 10, size: '300x600' }, + { sizeId: 13, size: '200x200' }, + { sizeId: 14, size: '250x250' }, + { sizeId: 15, size: '300x250' }, + { sizeId: 16, size: '336x280' }, + { sizeId: 19, size: '300x100' }, + { sizeId: 31, size: '980x120' }, + { sizeId: 32, size: '250x360' } // Create convenience properties for [sizeAsArray, width, height] by parsing the size string ].map(item => { const sizeAsArray = item.size.split('x').map(s => parseInt(s)); @@ -581,25 +581,25 @@ describe('the rubicon adapter', function () { expect(data.get('rp_hard_floor')).to.be.null; // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR', floor: 1.0}; + getFloorResponse = { currency: 'EUR', floor: 1.0 }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); data = new URLSearchParams(request.data); expect(data.get('rp_hard_floor')).to.be.null; // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR'}; + getFloorResponse = { currency: 'EUR' }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); data = new URLSearchParams(request.data); expect(data.get('rp_hard_floor')).to.be.null; // make it respond with USD floor and string floor - getFloorResponse = {currency: 'USD', floor: '1.23'}; + getFloorResponse = { currency: 'USD', floor: '1.23' }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); data = new URLSearchParams(request.data); expect(data.get('rp_hard_floor')).to.equal('1.23'); // make it respond with USD floor and num floor - getFloorResponse = {currency: 'USD', floor: 1.23}; + getFloorResponse = { currency: 'USD', floor: 1.23 }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); data = new URLSearchParams(request.data); expect(data.get('rp_hard_floor')).to.equal('1.23'); @@ -670,7 +670,7 @@ describe('the rubicon adapter', function () { }); it('should correctly send p_pos in sra fashion', function() { - config.setConfig({rubicon: {singleRequest: true}}); + config.setConfig({ rubicon: { singleRequest: true } }); // first one is atf var sraPosRequest = utils.deepClone(bidderRequest); @@ -702,7 +702,7 @@ describe('the rubicon adapter', function () { it('should correctly send cdep signal when requested', () => { var badposRequest = utils.deepClone(bidderRequest); - badposRequest.bids[0].ortb2 = {device: {ext: {cdep: 3}}}; + badposRequest.bids[0].ortb2 = { device: { ext: { cdep: 3 } } }; const [request] = spec.buildRequests(badposRequest.bids, badposRequest); const data = new URLSearchParams(request.data); @@ -815,7 +815,7 @@ describe('the rubicon adapter', function () { ] }; - bidderRequest = Object.assign({refererInfo}, bidderRequest); + bidderRequest = Object.assign({ refererInfo }, bidderRequest); delete bidderRequest.bids[0].params.referrer; const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); @@ -828,8 +828,8 @@ describe('the rubicon adapter', function () { expect(new URLSearchParams(request.data).get('rf')).to.equal('localhost'); delete bidderRequest.bids[0].params.referrer; - const refererInfo = {page: 'https://www.prebid.org'}; - bidderRequest = Object.assign({refererInfo}, bidderRequest); + const refererInfo = { page: 'https://www.prebid.org' }; + bidderRequest = Object.assign({ refererInfo }, bidderRequest); [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(new URLSearchParams(request.data).get('rf')).to.equal('https://www.prebid.org'); @@ -1073,7 +1073,7 @@ describe('the rubicon adapter', function () { }], gender: 'M', yob: '1984', - geo: {country: 'ca'}, + geo: { country: 'ca' }, keywords: 'd', ext: { data: { @@ -1103,7 +1103,7 @@ describe('the rubicon adapter', function () { }; // get the built request - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest); + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2 })), bidderRequest); const data = new URLSearchParams(request.data); // make sure that tg_v, tg_i, and kw values are correct @@ -1118,7 +1118,7 @@ describe('the rubicon adapter', function () { it('should group all bid requests with the same site id', function () { sandbox.stub(Math, 'random').callsFake(() => 0.1); - config.setConfig({rubicon: {singleRequest: true}}); + config.setConfig({ rubicon: { singleRequest: true } }); const expectedQuery = { 'account_id': '14062', @@ -1225,7 +1225,7 @@ describe('the rubicon adapter', function () { }); it('should not send more than 10 bids in a request (split into separate requests with <= 10 bids each)', function () { - config.setConfig({rubicon: {singleRequest: true}}); + config.setConfig({ rubicon: { singleRequest: true } }); let serverRequests; let data; @@ -1291,7 +1291,7 @@ describe('the rubicon adapter', function () { }); it('should not group bid requests if singleRequest does not equal true', function () { - config.setConfig({rubicon: {singleRequest: false}}); + config.setConfig({ rubicon: { singleRequest: false } }); const bidCopy = utils.deepClone(bidderRequest.bids[0]); bidderRequest.bids.push(bidCopy); @@ -1309,7 +1309,7 @@ describe('the rubicon adapter', function () { }); it('should not group video bid requests', function () { - config.setConfig({rubicon: {singleRequest: true}}); + config.setConfig({ rubicon: { singleRequest: true } }); const bidCopy = utils.deepClone(bidderRequest.bids[0]); bidderRequest.bids.push(bidCopy); @@ -1602,7 +1602,7 @@ describe('the rubicon adapter', function () { }); describe('Config user.id support', function () { it('should send ppuid when config defines user.id', function () { - config.setConfig({user: {id: '123'}}); + config.setConfig({ user: { id: '123' } }); const clonedBid = utils.deepClone(bidderRequest.bids[0]); clonedBid.userId = { pubcid: '1111' @@ -1756,7 +1756,7 @@ describe('the rubicon adapter', function () { }]; const expectedTransparency = 'testdomain.com~1'; - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2: ortb2Clone })), bidderRequest); const data = new URLSearchParams(request.data); expect(data.get('dsatransparency')).to.equal(expectedTransparency); @@ -1769,7 +1769,7 @@ describe('the rubicon adapter', function () { params: [], }]; - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2: ortb2Clone })), bidderRequest); const data = new URLSearchParams(request.data); expect(data.get('dsatransparency')).to.be.null }) @@ -1781,14 +1781,14 @@ describe('the rubicon adapter', function () { dsaparams: [1], }]; - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest); + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2: ortb2Clone })), bidderRequest); const data = new URLSearchParams(request.data); expect(data.get('dsatransparency')).to.be.null }) it('should send dsa signals if \"ortb2.regs.ext.dsa\"', function() { const expectedTransparency = 'testdomain.com~1~~testdomain2.com~1_2' - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest) + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2 })), bidderRequest) const data = new URLSearchParams(request.data); expect(typeof data).to.equal('object'); @@ -1806,7 +1806,7 @@ describe('the rubicon adapter', function () { const expectedTransparency = 'testdomain.com~1'; const ortb2Clone = deepClone(ortb2); ortb2Clone.regs.ext.dsa.transparency.pop() - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2: ortb2Clone})), bidderRequest) + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2: ortb2Clone })), bidderRequest) const data = new URLSearchParams(request.data); expect(typeof data).to.equal('object'); @@ -1815,7 +1815,7 @@ describe('the rubicon adapter', function () { }) }) - it('should send gpid and pbadslot since it is prefered over dfp code', function () { + it('should send gpid and pbadslot since it is preferred over dfp code', function () { bidderRequest.bids[0].ortb2Imp = { ext: { gpid: '/1233/sports&div1', @@ -2043,33 +2043,37 @@ describe('the rubicon adapter', function () { }); it('should not send high entropy if not present when it is low entropy client hints', function () { const bidRequestSua = utils.deepClone(bidderRequest); - bidRequestSua.bids[0].ortb2 = { device: { sua: { - 'source': 1, - 'platform': { - 'brand': 'macOS' - }, - 'browsers': [ - { - 'brand': 'Not A(Brand', - 'version': [ - '8' - ] - }, - { - 'brand': 'Chromium', - 'version': [ - '132' - ] - }, - { - 'brand': 'Google Chrome', - 'version': [ - '132' - ] + bidRequestSua.bids[0].ortb2 = { + device: { + sua: { + 'source': 1, + 'platform': { + 'brand': 'macOS' + }, + 'browsers': [ + { + 'brand': 'Not A(Brand', + 'version': [ + '8' + ] + }, + { + 'brand': 'Chromium', + 'version': [ + '132' + ] + }, + { + 'brand': 'Google Chrome', + 'version': [ + '132' + ] + } + ], + 'mobile': 0 } - ], - 'mobile': 0 - } } }; + } + }; // How should fastlane query be constructed with default SUA const expectedValues = { @@ -2097,14 +2101,18 @@ describe('the rubicon adapter', function () { }); it('should ignore invalid browser hints (missing version)', function () { const bidRequestSua = utils.deepClone(bidderRequest); - bidRequestSua.bids[0].ortb2 = { device: { sua: { - 'browsers': [ - { - 'brand': 'Not A(Brand', - // 'version': ['8'], // missing version - }, - ], - } } }; + bidRequestSua.bids[0].ortb2 = { + device: { + sua: { + 'browsers': [ + { + 'brand': 'Not A(Brand', + // 'version': ['8'], // missing version + }, + ], + } + } + }; // How should fastlane query be constructed with default SUA const expectedValues = { @@ -2165,7 +2173,7 @@ describe('the rubicon adapter', function () { expect(imp.ext.prebid.bidder.rubicon.video.skipafter).to.equal(15); expect(post.ext.prebid.auctiontimestamp).to.equal(1472239426000); // should contain version - expect(post.ext.prebid.channel).to.deep.equal({name: 'pbjs', version: getGlobal().version}); + expect(post.ext.prebid.channel).to.deep.equal({ name: 'pbjs', version: getGlobal().version }); expect(post.user.ext.consent).to.equal('BOJ/P2HOJ/P2HABABMAAAAAZ+A=='); // EIDs should exist expect(post.user.ext).to.have.property('eids').that.is.an('array'); @@ -2277,22 +2285,22 @@ describe('the rubicon adapter', function () { expect(request.data.imp[0].bidfloor).to.be.undefined; // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR', floor: 1.0}; + getFloorResponse = { currency: 'EUR', floor: 1.0 }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.imp[0].bidfloor).to.be.undefined; // make it respond with a non USD floor should not send it - getFloorResponse = {currency: 'EUR'}; + getFloorResponse = { currency: 'EUR' }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.imp[0].bidfloor).to.be.undefined; // make it respond with USD floor and string floor - getFloorResponse = {currency: 'USD', floor: '1.23'}; + getFloorResponse = { currency: 'USD', floor: '1.23' }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.imp[0].bidfloor).to.equal(1.23); // make it respond with USD floor and num floor - getFloorResponse = {currency: 'USD', floor: 1.23}; + getFloorResponse = { currency: 'USD', floor: 1.23 }; [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.imp[0].bidfloor).to.equal(1.23); }); @@ -2327,7 +2335,7 @@ describe('the rubicon adapter', function () { // should have the aliases object sent to PBS expect(request.data.ext.prebid).to.haveOwnProperty('aliases'); - expect(request.data.ext.prebid.aliases).to.deep.equal({superRubicon: 'rubicon'}); + expect(request.data.ext.prebid.aliases).to.deep.equal({ superRubicon: 'rubicon' }); // should have the imp ext bidder params be under the alias name not rubicon superRubicon expect(request.data.imp[0].ext.prebid.bidder).to.have.property('superRubicon').that.is.an('object'); @@ -2368,7 +2376,7 @@ describe('the rubicon adapter', function () { maxbids: 2 }]; - config.setConfig({multibid: multibid}); + config.setConfig({ multibid: multibid }); const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); @@ -2384,7 +2392,7 @@ describe('the rubicon adapter', function () { const payload = request.data; expect(payload.ext.prebid.analytics).to.not.be.undefined; - expect(payload.ext.prebid.analytics).to.deep.equal({'rubicon': {'client-analytics': true}}); + expect(payload.ext.prebid.analytics).to.deep.equal({ 'rubicon': { 'client-analytics': true } }); }); it('should pass client analytics to PBS endpoint if rubicon analytics adapter is included', function () { @@ -2394,7 +2402,7 @@ describe('the rubicon adapter', function () { const payload = request.data; expect(payload.ext.prebid.analytics).to.not.be.undefined; - expect(payload.ext.prebid.analytics).to.deep.equal({'rubicon': {'client-analytics': true}}); + expect(payload.ext.prebid.analytics).to.deep.equal({ 'rubicon': { 'client-analytics': true } }); }); it('should not pass client analytics to PBS endpoint if rubicon analytics adapter is not included', function () { @@ -2651,11 +2659,11 @@ describe('the rubicon adapter', function () { } }, content: { - data: [{foo: 'bar'}] + data: [{ foo: 'bar' }] }, keywords: 'e,f', rating: '4-star', - data: [{foo: 'bar'}] + data: [{ foo: 'bar' }] }; const user = { ext: { @@ -2666,8 +2674,8 @@ describe('the rubicon adapter', function () { keywords: 'd', gender: 'M', yob: '1984', - geo: {country: 'ca'}, - data: [{foo: 'bar'}] + geo: { country: 'ca' }, + data: [{ foo: 'bar' }] }; const ortb2 = { @@ -2675,10 +2683,10 @@ describe('the rubicon adapter', function () { user }; - const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({...b, ortb2})), bidderRequest); + const [request] = spec.buildRequests(bidderRequest.bids.map((b) => ({ ...b, ortb2 })), bidderRequest); const expected = { - site: Object.assign({}, site, {keywords: bidderRequest.bids[0].params.keywords.join(',')}), + site: Object.assign({}, site, { keywords: bidderRequest.bids[0].params.keywords.join(',') }), user: Object.assign({}, user), siteData: Object.assign({}, site.ext.data, bidderRequest.bids[0].params.inventory), userData: Object.assign({}, user.ext.data, bidderRequest.bids[0].params.visitor), @@ -2762,13 +2770,13 @@ describe('the rubicon adapter', function () { it('should use the integration type provided in the config instead of the default', () => { const bidderRequest = createVideoBidderRequest(); - config.setConfig({rubicon: {int_type: 'testType'}}); + config.setConfig({ rubicon: { int_type: 'testType' } }); const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(request.data.ext.prebid.bidders.rubicon.integration).to.equal('testType'); }); it('should pass the user.id provided in the config', async function () { - config.setConfig({user: {id: '123'}}); + config.setConfig({ user: { id: '123' } }); const bidderRequest = createVideoBidderRequest(); sandbox.stub(Date, 'now').callsFake(() => @@ -2820,29 +2828,29 @@ describe('the rubicon adapter', function () { it('should combine an array of slot url params', function () { expect(spec.combineSlotUrlParams([])).to.deep.equal({}); - expect(spec.combineSlotUrlParams([{p1: 'foo', p2: 'test', p3: ''}])).to.deep.equal({ + expect(spec.combineSlotUrlParams([{ p1: 'foo', p2: 'test', p3: '' }])).to.deep.equal({ p1: 'foo', p2: 'test', p3: '' }); - expect(spec.combineSlotUrlParams([{}, {p1: 'foo', p2: 'test'}])).to.deep.equal({p1: ';foo', p2: ';test'}); + expect(spec.combineSlotUrlParams([{}, { p1: 'foo', p2: 'test' }])).to.deep.equal({ p1: ';foo', p2: ';test' }); - expect(spec.combineSlotUrlParams([{}, {}, {p1: 'foo', p2: ''}, {}])).to.deep.equal({p1: ';;foo;', p2: ''}); + expect(spec.combineSlotUrlParams([{}, {}, { p1: 'foo', p2: '' }, {}])).to.deep.equal({ p1: ';;foo;', p2: '' }); - expect(spec.combineSlotUrlParams([{}, {p1: 'foo'}, {p1: ''}])).to.deep.equal({p1: ';foo;'}); + expect(spec.combineSlotUrlParams([{}, { p1: 'foo' }, { p1: '' }])).to.deep.equal({ p1: ';foo;' }); expect(spec.combineSlotUrlParams([ - {p1: 'foo', p2: 'test'}, - {p2: 'test', p3: 'bar'}, - {p1: 'bar', p2: 'test', p4: 'bar'} - ])).to.deep.equal({p1: 'foo;;bar', p2: 'test', p3: ';bar;', p4: ';;bar'}); + { p1: 'foo', p2: 'test' }, + { p2: 'test', p3: 'bar' }, + { p1: 'bar', p2: 'test', p4: 'bar' } + ])).to.deep.equal({ p1: 'foo;;bar', p2: 'test', p3: ';bar;', p4: ';;bar' }); expect(spec.combineSlotUrlParams([ - {p1: 'foo', p2: 'test', p3: 'baz'}, - {p1: 'foo', p2: 'bar'}, - {p2: 'test'} - ])).to.deep.equal({p1: 'foo;foo;', p2: 'test;bar;test', p3: 'baz;;'}); + { p1: 'foo', p2: 'test', p3: 'baz' }, + { p1: 'foo', p2: 'bar' }, + { p2: 'test' } + ])).to.deep.equal({ p1: 'foo;foo;', p2: 'test;bar;test', p3: 'baz;;' }); }); }); @@ -2949,13 +2957,13 @@ describe('the rubicon adapter', function () { it('Should return false if both banner and video mediaTypes are set and params.video is not an object', function () { removeVideoParamFromBidderRequest(bidderRequest); const bid = bidderRequest.bids[0]; - bid.mediaTypes.banner = {flag: true}; + bid.mediaTypes.banner = { flag: true }; expect(classifiedAsVideo(bid)).to.equal(false); }); it('Should return true if both banner and video mediaTypes are set and params.video is an object', function () { removeVideoParamFromBidderRequest(bidderRequest); const bid = bidderRequest.bids[0]; - bid.mediaTypes.banner = {flag: true}; + bid.mediaTypes.banner = { flag: true }; bid.params.video = {}; expect(classifiedAsVideo(bid)).to.equal(true); }); @@ -3113,8 +3121,8 @@ describe('the rubicon adapter', function () { describe('with duplicate adUnitCodes', () => { it('should increment PBS request imp[].id starting at 2', () => { - const nativeBidderRequest = addNativeToBidRequest(bidderRequest, {twin: true}); - const request = converter.toORTB({bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids}); + const nativeBidderRequest = addNativeToBidRequest(bidderRequest, { twin: true }); + const request = converter.toORTB({ bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids }); for (let i = 0; i < nativeBidderRequest.bids.length; i++) { var adUnitCode = nativeBidderRequest.bids[i].adUnitCode; if (i === 0) { @@ -3191,7 +3199,7 @@ describe('the rubicon adapter', function () { ] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); @@ -3294,7 +3302,7 @@ describe('the rubicon adapter', function () { netRevenue: false } }); - let bids = spec.interpretResponse({body: response}, { + let bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(2); @@ -3307,7 +3315,7 @@ describe('the rubicon adapter', function () { netRevenue: true } }); - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(2); @@ -3320,7 +3328,7 @@ describe('the rubicon adapter', function () { netRevenue: undefined } }); - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(2); @@ -3333,7 +3341,7 @@ describe('the rubicon adapter', function () { netRevenue: 'someString' } }); - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(2); @@ -3379,7 +3387,7 @@ describe('the rubicon adapter', function () { } ]; - let bids = spec.interpretResponse({body: response}, { + let bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].creativeId).to.equal('8-7'); @@ -3405,7 +3413,7 @@ describe('the rubicon adapter', function () { } ]; - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].creativeId).to.equal('-'); @@ -3432,7 +3440,7 @@ describe('the rubicon adapter', function () { } ]; - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].creativeId).to.equal('8-'); @@ -3459,7 +3467,7 @@ describe('the rubicon adapter', function () { } ]; - bids = spec.interpretResponse({body: response}, { + bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].creativeId).to.equal('-7'); @@ -3484,7 +3492,7 @@ describe('the rubicon adapter', function () { }] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); @@ -3561,7 +3569,7 @@ describe('the rubicon adapter', function () { } ] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids).to.be.lengthOf(2); @@ -3701,9 +3709,9 @@ describe('the rubicon adapter', function () { ] }; - config.setConfig({ multibid: [{bidder: 'rubicon', maxbids: 2, targetbiddercodeprefix: 'rubi'}] }); + config.setConfig({ multibid: [{ bidder: 'rubicon', maxbids: 2, targetbiddercodeprefix: 'rubi' }] }); - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidRequests }); @@ -3727,7 +3735,7 @@ describe('the rubicon adapter', function () { 'ads': [] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); @@ -3751,7 +3759,7 @@ describe('the rubicon adapter', function () { }] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); @@ -3761,7 +3769,7 @@ describe('the rubicon adapter', function () { it('should handle an error because of malformed json response', function () { const response = '{test{'; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); @@ -3787,7 +3795,7 @@ describe('the rubicon adapter', function () { }] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: [utils.deepClone(bidderRequest.bids[0])] }); @@ -3853,7 +3861,7 @@ describe('the rubicon adapter', function () { } ] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].meta.mediaType).to.equal('banner'); @@ -3941,7 +3949,7 @@ describe('the rubicon adapter', function () { } ] }; - const bids = spec.interpretResponse({body: response}, { + const bids = spec.interpretResponse({ body: response }, { bidRequest: bidderRequest.bids[0] }); expect(bids[0].meta.primaryCatId).to.be.undefined; @@ -3955,7 +3963,7 @@ describe('the rubicon adapter', function () { describe('singleRequest enabled', function () { it('handles bidRequest of type Array and returns associated adUnits', function () { const overrideMap = []; - overrideMap[0] = {impression_id: '1'}; + overrideMap[0] = { impression_id: '1' }; const stubAds = []; for (let i = 0; i < 10; i++) { @@ -3978,7 +3986,7 @@ describe('the rubicon adapter', function () { 'inventory': {}, 'ads': stubAds } - }, {bidRequest: stubBids}); + }, { bidRequest: stubBids }); expect(bids).to.be.a('array').with.lengthOf(10); bids.forEach((bid) => { @@ -4011,7 +4019,7 @@ describe('the rubicon adapter', function () { it('handles incorrect adUnits length by returning all bids with matching ads', function () { const overrideMap = []; - overrideMap[0] = {impression_id: '1'}; + overrideMap[0] = { impression_id: '1' }; const stubAds = []; for (let i = 0; i < 6; i++) { @@ -4034,7 +4042,7 @@ describe('the rubicon adapter', function () { 'inventory': {}, 'ads': stubAds } - }, {bidRequest: stubBids}); + }, { bidRequest: stubBids }); // no bids expected because response didn't match requested bid number expect(bids).to.be.a('array').with.lengthOf(6); @@ -4045,11 +4053,11 @@ describe('the rubicon adapter', function () { // Create overrides to break associations between bids and ads // Each override should cause one less bid to be returned by interpretResponse const overrideMap = []; - overrideMap[0] = {impression_id: '1'}; - overrideMap[2] = {status: 'error'}; - overrideMap[4] = {status: 'error'}; - overrideMap[7] = {status: 'error'}; - overrideMap[8] = {status: 'error'}; + overrideMap[0] = { impression_id: '1' }; + overrideMap[2] = { status: 'error' }; + overrideMap[4] = { status: 'error' }; + overrideMap[7] = { status: 'error' }; + overrideMap[8] = { status: 'error' }; for (let i = 0; i < 10; i++) { stubAds.push(createResponseAdByIndex(i, sizeMap[i].sizeId, overrideMap)); @@ -4071,7 +4079,7 @@ describe('the rubicon adapter', function () { 'inventory': {}, 'ads': stubAds } - }, {bidRequest: stubBids}); + }, { bidRequest: stubBids }); expect(bids).to.be.a('array').with.lengthOf(6); bids.forEach((bid) => { @@ -4140,9 +4148,9 @@ describe('the rubicon adapter', function () { }], }; - const request = converter.toORTB({bidderRequest, bidRequests: bidderRequest.bids}); + const request = converter.toORTB({ bidderRequest, bidRequests: bidderRequest.bids }); - const bids = spec.interpretResponse({body: response}, {data: request}); + const bids = spec.interpretResponse({ body: response }, { data: request }); expect(bids).to.be.lengthOf(1); @@ -4151,7 +4159,7 @@ describe('the rubicon adapter', function () { expect(bids[0].cpm).to.equal(2); expect(bids[0].ttl).to.equal(360); expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].adserverTargeting).to.deep.equal({hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64'}); + expect(bids[0].adserverTargeting).to.deep.equal({ hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64' }); expect(bids[0].mediaType).to.equal('video'); expect(bids[0].meta.mediaType).to.equal('video'); expect(String(bids[0].meta.advertiserDomains)).to.equal('test.com'); @@ -4168,18 +4176,18 @@ describe('the rubicon adapter', function () { describe('for native', () => { it('should get a native bid', () => { const nativeBidderRequest = addNativeToBidRequest(bidderRequest); - const request = converter.toORTB({bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids}); - const response = getNativeResponse({impid: request.imp[0].id}); - const bids = spec.interpretResponse({body: response}, {data: request}); + const request = converter.toORTB({ bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids }); + const response = getNativeResponse({ impid: request.imp[0].id }); + const bids = spec.interpretResponse({ body: response }, { data: request }); expect(bids).to.have.nested.property('[0].native'); }); it('should set 0 to bids width and height if `w` and `h` in response object not defined', () => { const nativeBidderRequest = addNativeToBidRequest(bidderRequest); - const request = converter.toORTB({bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids}); - const response = getNativeResponse({impid: request.imp[0].id}); + const request = converter.toORTB({ bidderRequest: nativeBidderRequest, bidRequests: nativeBidderRequest.bids }); + const response = getNativeResponse({ impid: request.imp[0].id }); delete response.seatbid[0].bid[0].w; delete response.seatbid[0].bid[0].h - const bids = spec.interpretResponse({body: response}, {data: request}); + const bids = spec.interpretResponse({ body: response }, { data: request }); expect(bids[0].width).to.equal(0); expect(bids[0].height).to.equal(0); }); @@ -4190,14 +4198,16 @@ describe('the rubicon adapter', function () { describe('for outstream video', function () { const sandbox = sinon.createSandbox(); beforeEach(function () { - config.setConfig({rubicon: { - rendererConfig: { - align: 'left', - closeButton: true, - collapse: false - }, - rendererUrl: 'https://example.test/renderer.js' - }}); + config.setConfig({ + rubicon: { + rendererConfig: { + align: 'left', + closeButton: true, + collapse: false + }, + rendererUrl: 'https://example.test/renderer.js' + } + }); window.MagniteApex = { renderAd: function() { return null; @@ -4242,9 +4252,9 @@ describe('the rubicon adapter', function () { }], }; - const request = converter.toORTB({bidderRequest, bidRequests: bidderRequest.bids}); + const request = converter.toORTB({ bidderRequest, bidRequests: bidderRequest.bids }); - const bids = spec.interpretResponse({body: response}, { data: request }); + const bids = spec.interpretResponse({ body: response }, { data: request }); expect(bids).to.be.lengthOf(1); @@ -4253,7 +4263,7 @@ describe('the rubicon adapter', function () { expect(bids[0].cpm).to.equal(2); expect(bids[0].ttl).to.equal(360); expect(bids[0].netRevenue).to.equal(true); - expect(bids[0].adserverTargeting).to.deep.equal({hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64'}); + expect(bids[0].adserverTargeting).to.deep.equal({ hb_uuid: '0c498f63-5111-4bed-98e2-9be7cb932a64' }); expect(bids[0].mediaType).to.equal('video'); expect(bids[0].meta.mediaType).to.equal('video'); expect(String(bids[0].meta.advertiserDomains)).to.equal('test.com'); @@ -4305,11 +4315,11 @@ describe('the rubicon adapter', function () { }], }; - const request = converter.toORTB({bidderRequest, bidRequests: bidderRequest.bids}); + const request = converter.toORTB({ bidderRequest, bidRequests: bidderRequest.bids }); sinon.spy(window.MagniteApex, 'renderAd'); - const bids = spec.interpretResponse({body: response}, {data: request}); + const bids = spec.interpretResponse({ body: response }, { data: request }); const bid = bids[0]; bid.adUnitCode = 'outstream_video1_placement'; const adUnit = document.createElement('div'); @@ -4375,11 +4385,11 @@ describe('the rubicon adapter', function () { }], }; - const request = converter.toORTB({bidderRequest, bidRequests: bidderRequest.bids}); + const request = converter.toORTB({ bidderRequest, bidRequests: bidderRequest.bids }); sinon.spy(window.MagniteApex, 'renderAd'); - const bids = spec.interpretResponse({body: response}, {data: request}); + const bids = spec.interpretResponse({ body: response }, { data: request }); const bid = bids[0]; bid.adUnitCode = 'outstream_video1_placement'; const adUnit = document.createElement('div'); @@ -4411,7 +4421,7 @@ describe('the rubicon adapter', function () { describe('config with integration type', () => { it('should use the integration type provided in the config instead of the default', () => { - config.setConfig({rubicon: {int_type: 'testType'}}); + config.setConfig({ rubicon: { int_type: 'testType' } }); const [request] = spec.buildRequests(bidderRequest.bids, bidderRequest); expect(new URLSearchParams(request.data).get('tk_flint')).to.equal('testType_v$prebid.version$'); }); @@ -4427,24 +4437,24 @@ describe('the rubicon adapter', function () { iframeEnabled: true }); - expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); + expect(syncs).to.deep.equal({ type: 'iframe', url: emilyUrl }); }); it('should register the Emily iframe more than once', function () { let syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); + expect(syncs).to.deep.equal({ type: 'iframe', url: emilyUrl }); // when called again, should still have only been called once syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs).to.deep.equal({type: 'iframe', url: emilyUrl}); + expect(syncs).to.deep.equal({ type: 'iframe', url: emilyUrl }); }); it('should pass gdpr params if consent is true', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?gdpr=1&gdpr_consent=foo` @@ -4452,7 +4462,7 @@ describe('the rubicon adapter', function () { }); it('should pass gdpr params if consent is false', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: false, consentString: 'foo' })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?gdpr=0&gdpr_consent=foo` @@ -4460,7 +4470,7 @@ describe('the rubicon adapter', function () { }); it('should pass gdpr param gdpr_consent only when gdprApplies is undefined', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: 'foo' })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?gdpr_consent=foo` @@ -4468,13 +4478,13 @@ describe('the rubicon adapter', function () { }); it('should pass no params if gdpr consentString is not defined', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, {})).to.deep.equal({ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {})).to.deep.equal({ type: 'iframe', url: `${emilyUrl}` }); }); it('should pass no params if gdpr consentString is a number', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: 0 })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}` @@ -4482,7 +4492,7 @@ describe('the rubicon adapter', function () { }); it('should pass no params if gdpr consentString is null', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: null })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}` @@ -4490,7 +4500,7 @@ describe('the rubicon adapter', function () { }); it('should pass no params if gdpr consentString is a object', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: {} })).to.deep.equal({ type: 'iframe', url: `${emilyUrl}` @@ -4498,19 +4508,19 @@ describe('the rubicon adapter', function () { }); it('should pass no params if gdpr is not defined', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, undefined)).to.deep.equal({ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined)).to.deep.equal({ type: 'iframe', url: `${emilyUrl}` }); }); it('should pass us_privacy if uspConsent is defined', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, undefined, '1NYN')).to.deep.equal({ + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, undefined, '1NYN')).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?us_privacy=1NYN` }); }); it('should pass us_privacy after gdpr if both are present', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: 'foo' }, '1NYN')).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?gdpr_consent=foo&us_privacy=1NYN` @@ -4518,7 +4528,7 @@ describe('the rubicon adapter', function () { }); it('should pass gdprApplies', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true }, '1NYN')).to.deep.equal({ type: 'iframe', url: `${emilyUrl}?gdpr=1&us_privacy=1NYN` @@ -4526,7 +4536,7 @@ describe('the rubicon adapter', function () { }); it('should pass all correctly', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, { gdprApplies: true, consentString: 'foo' }, '1NYN')).to.deep.equal({ @@ -4535,7 +4545,7 @@ describe('the rubicon adapter', function () { }); it('should pass gpp params when gppConsent is present', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, {}, undefined, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {}, undefined, { gppString: 'foo', applicableSections: [2] })).to.deep.equal({ @@ -4544,7 +4554,7 @@ describe('the rubicon adapter', function () { }); it('should pass multiple sid\'s when multiple are present', function () { - expect(spec.getUserSyncs({iframeEnabled: true}, {}, {}, undefined, { + expect(spec.getUserSyncs({ iframeEnabled: true }, {}, {}, undefined, { gppString: 'foo', applicableSections: [2, 5] })).to.deep.equal({ @@ -4555,7 +4565,7 @@ describe('the rubicon adapter', function () { describe('get price granularity', function () { it('should return correct buckets for all price granularity values', function () { - const CUSTOM_PRICE_BUCKET_ITEM = {max: 5, increment: 0.5}; + const CUSTOM_PRICE_BUCKET_ITEM = { max: 5, increment: 0.5 }; const mockConfig = { priceGranularity: undefined, @@ -4568,12 +4578,12 @@ describe('the rubicon adapter', function () { }); [ - {key: 'low', val: {max: 5.00, increment: 0.50}}, - {key: 'medium', val: {max: 20.00, increment: 0.10}}, - {key: 'high', val: {max: 20.00, increment: 0.01}}, - {key: 'auto', val: {max: 5.00, increment: 0.05}}, - {key: 'dense', val: {max: 3.00, increment: 0.01}}, - {key: 'custom', val: CUSTOM_PRICE_BUCKET_ITEM}, + { key: 'low', val: { max: 5.00, increment: 0.50 } }, + { key: 'medium', val: { max: 20.00, increment: 0.10 } }, + { key: 'high', val: { max: 20.00, increment: 0.01 } }, + { key: 'auto', val: { max: 5.00, increment: 0.05 } }, + { key: 'dense', val: { max: 3.00, increment: 0.01 } }, + { key: 'custom', val: CUSTOM_PRICE_BUCKET_ITEM }, ].forEach(kvPair => { mockConfig.priceGranularity = kvPair.key; @@ -4722,12 +4732,12 @@ describe('the rubicon adapter', function () { const syncs = spec.getUserSyncs({ iframeEnabled: true }); - expect(syncs).to.deep.equal({type: 'iframe', url: 'https://eus-qa.rubiconproject.com/usync.html'}); + expect(syncs).to.deep.equal({ type: 'iframe', url: 'https://eus-qa.rubiconproject.com/usync.html' }); }); }); }); -function addNativeToBidRequest(bidderRequest, options = {twin: false}) { +function addNativeToBidRequest(bidderRequest, options = { twin: false }) { const nativeOrtbRequest = { assets: [{ id: 0, @@ -4784,7 +4794,7 @@ function addNativeToBidRequest(bidderRequest, options = {twin: false}) { return bidderRequest; } -function getNativeResponse(options = {impid: 1234}) { +function getNativeResponse(options = { impid: 1234 }) { return { 'id': 'd7786a80-bfb4-4541-859f-225a934e81d4', 'seatbid': [ diff --git a/test/spec/modules/rules_spec.js b/test/spec/modules/rules_spec.js new file mode 100644 index 00000000000..24f73a33513 --- /dev/null +++ b/test/spec/modules/rules_spec.js @@ -0,0 +1,856 @@ +import { expect } from 'chai'; +import * as rulesModule from 'modules/rules/index.ts'; +import * as utils from 'src/utils.js'; +import * as storageManager from 'src/storageManager.js'; +import * as analyticsAdapter from 'libraries/analyticsAdapter/AnalyticsAdapter.ts'; +import { isActivityAllowed } from 'src/activities/rules.js'; +import { activityParams } from 'src/activities/activityParams.js'; +import { ACTIVITY_FETCH_BIDS, ACTIVITY_ADD_BID_RESPONSE } from 'src/activities/activities.js'; +import { MODULE_TYPE_BIDDER } from 'src/activities/modules.ts'; +import { config } from 'src/config.js'; + +describe('Rules Module', function() { + let sandbox; + let logWarnStub; + let logInfoStub; + let newStorageManagerStub; + + beforeEach(function() { + sandbox = sinon.createSandbox(); + + logWarnStub = sandbox.stub(utils, 'logWarn'); + logInfoStub = sandbox.stub(utils, 'logInfo'); + + const mockStorageManager = { + localStorageIsEnabled: sandbox.stub().returns(true), + getDataFromLocalStorage: sandbox.stub().returns(null), + setDataInLocalStorage: sandbox.stub() + }; + newStorageManagerStub = sandbox.stub(storageManager, 'newStorageManager').returns(mockStorageManager); + }); + + afterEach(function() { + sandbox.restore(); + config.resetConfig(); + rulesModule.reset(); + }); + + describe('getAssignedModelGroups', function() { + it('should select model group based on weights', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + weight: 50, + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + weight: 50, + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }] + }]; + + // Mock Math.random to return 0.15 (15 < 50, so first group should be selected) + // randomValue = 0.15 * 100 = 15, 15 < 50 so first group selected + sandbox.stub(Math, 'random').returns(0.15); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + // Verify that first model group was selected in the returned result + expect(result[0].modelGroups[0].selected).to.be.true; + expect(result[0].modelGroups[1].selected).to.be.false; + // Verify original was not mutated + expect(rulesets[0].modelGroups[0].selected).to.be.false; + expect(rulesets[0].modelGroups[1].selected).to.be.false; + }); + + it('should use default weight of 100 when weight is not specified', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + // weight not specified, should default to 100 + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + // weight not specified, should default to 100 + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }, { + // weight not specified, should default to 100 + selected: false, + analyticsKey: 'testKey3', + schema: [], + rules: [] + }] + }]; + + // Mock Math.random to return value that selects last group + // randomValue = 0.85 * 300 = 255 + // Cumulative weights: [100, 200, 300] + // First group: 255 < 100? No + // Second group: 255 < 200? No + // Third group: 255 < 300? Yes, selected! + sandbox.stub(Math, 'random').returns(0.85); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + expect(result[0].modelGroups[0].selected).to.be.false; + expect(result[0].modelGroups[1].selected).to.be.false; + expect(result[0].modelGroups[2].selected).to.be.true; + // Verify original was not mutated + expect(rulesets[0].modelGroups[0].selected).to.be.false; + expect(rulesets[0].modelGroups[1].selected).to.be.false; + expect(rulesets[0].modelGroups[2].selected).to.be.false; + }); + + it('should select correctly regardless of weight order (descending)', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + weight: 100, // largest first + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + weight: 50, // medium + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }, { + weight: 25, // smallest last + selected: false, + analyticsKey: 'testKey3', + schema: [], + rules: [] + }] + }]; + + // randomValue = 0.3 * 175 = 52.5 + // Cumulative weights: [100, 150, 175] + // First group: 52.5 < 100? Yes, selected! + sandbox.stub(Math, 'random').returns(0.3); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + expect(result[0].modelGroups[0].selected).to.be.true; + expect(result[0].modelGroups[1].selected).to.be.false; + expect(result[0].modelGroups[2].selected).to.be.false; + }); + + it('should select correctly regardless of weight order (mixed)', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + weight: 30, // medium + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + weight: 100, // largest in middle + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }, { + weight: 20, // smallest last + selected: false, + analyticsKey: 'testKey3', + schema: [], + rules: [] + }] + }]; + + // randomValue = 0.6 * 150 = 90 + // Cumulative weights: [30, 130, 150] + // First group: 90 < 30? No + // Second group: 90 < 130? Yes, selected! + sandbox.stub(Math, 'random').returns(0.6); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + expect(result[0].modelGroups[0].selected).to.be.false; + expect(result[0].modelGroups[1].selected).to.be.true; + expect(result[0].modelGroups[2].selected).to.be.false; + }); + + it('should select last group when randomValue is in last range', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + weight: 10, + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + weight: 20, + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }, { + weight: 70, // largest weight + selected: false, + analyticsKey: 'testKey3', + schema: [], + rules: [] + }] + }]; + + // randomValue = 0.8 * 100 = 80 + // Cumulative weights: [10, 30, 100] + // First group: 80 < 10? No + // Second group: 80 < 30? No + // Third group: 80 < 100? Yes, selected! + sandbox.stub(Math, 'random').returns(0.8); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + expect(result[0].modelGroups[0].selected).to.be.false; + expect(result[0].modelGroups[1].selected).to.be.false; + expect(result[0].modelGroups[2].selected).to.be.true; + }); + + it('should select first group when randomValue is very small', function() { + const rulesets = [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + modelGroups: [{ + weight: 10, // smallest + selected: false, + analyticsKey: 'testKey1', + schema: [], + rules: [] + }, { + weight: 50, + selected: false, + analyticsKey: 'testKey2', + schema: [], + rules: [] + }, { + weight: 40, + selected: false, + analyticsKey: 'testKey3', + schema: [], + rules: [] + }] + }]; + + // randomValue = 0.01 * 100 = 1 + // Cumulative weights: [10, 60, 100] + // First group: 1 < 10? Yes, selected! + sandbox.stub(Math, 'random').returns(0.01); + + const result = rulesModule.getAssignedModelGroups(rulesets); + + expect(result[0].modelGroups[0].selected).to.be.true; + expect(result[0].modelGroups[1].selected).to.be.false; + expect(result[0].modelGroups[2].selected).to.be.false; + }); + }); + + describe('evaluateConfig', function() { + beforeEach(function() { + rulesModule.registerActivities(); + }); + + [ + ['processed-auction-request', ACTIVITY_FETCH_BIDS], + ['processed-auction', ACTIVITY_ADD_BID_RESPONSE] + ].forEach(([stage, activity]) => { + it(`should exclude bidder when it matches bidders list for ${stage} stage`, function() { + const rulesJson = { + enabled: true, + timestamp: '1234567890', + ruleSets: [{ + name: 'testRuleSet', + stage: stage, + version: '1.0', + modelGroups: [{ + weight: 100, + selected: true, + analyticsKey: 'testAnalyticsKey', + schema: [{ function: 'adUnitCode', args: [] }], + rules: [{ + conditions: ['adUnit-0000'], + results: [{ + function: 'excludeBidders', + args: [{ + bidders: ['bidder1'], + analyticsValue: 'excluded' + }] + }] + }] + }] + }] + }; + + sandbox.stub(Math, 'random').returns(0.5); + + const bidder1Params = activityParams(MODULE_TYPE_BIDDER, 'bidder1', { + adUnit: { code: 'adUnit-0000' }, + auctionId: 'test-auction-id' + }); + + const bidder2Params = activityParams(MODULE_TYPE_BIDDER, 'bidder2', { + adUnit: { code: 'adUnit-0000' }, + auctionId: 'test-auction-id' + }); + + expect(isActivityAllowed(activity, bidder1Params)).to.be.true; + expect(isActivityAllowed(activity, bidder2Params)).to.be.true; + + rulesModule.evaluateConfig(rulesJson, 'test-auction-id'); + + expect(isActivityAllowed(activity, bidder1Params)).to.be.false; + expect(isActivityAllowed(activity, bidder2Params)).to.be.true; + }); + + it(`should include only bidder when it matches bidders list for ${stage} stage`, function() { + const rulesJson = { + enabled: true, + timestamp: '1234567890', + ruleSets: [{ + name: 'testRuleSet', + stage: stage, + version: '1.0', + modelGroups: [{ + weight: 100, + selected: true, + analyticsKey: 'testAnalyticsKey', + schema: [{ function: 'adUnitCode', args: [] }], + rules: [{ + conditions: ['adUnit-0000'], + results: [{ + function: 'includeBidders', + args: [{ + bidders: ['bidder1'], + analyticsValue: 'included' + }] + }] + }] + }] + }] + }; + + sandbox.stub(Math, 'random').returns(0.5); + + const bidder1Params = activityParams(MODULE_TYPE_BIDDER, 'bidder1', { + adUnit: { code: 'adUnit-0000' }, + auctionId: 'test-auction-id' + }); + + const bidder2Params = activityParams(MODULE_TYPE_BIDDER, 'bidder2', { + adUnit: { code: 'adUnit-0000' }, + auctionId: 'test-auction-id' + }); + + expect(isActivityAllowed(activity, bidder1Params)).to.be.true; + expect(isActivityAllowed(activity, bidder2Params)).to.be.true; + + rulesModule.evaluateConfig(rulesJson, 'test-auction-id'); + + expect(isActivityAllowed(activity, bidder1Params)).to.be.true; + expect(isActivityAllowed(activity, bidder2Params)).to.be.false; + }); + }); + + it('should execute default rules when provided and no rules match', function() { + const setLabelsStub = sandbox.stub(analyticsAdapter, 'setLabels'); + const rulesJson = { + enabled: true, + timestamp: '1234567890', + ruleSets: [{ + name: 'testRuleSet', + stage: 'processed-auction-request', + version: '1.0', + modelGroups: [{ + weight: 100, + selected: true, + analyticsKey: 'testAnalyticsKey', + schema: [{ + function: 'percent', + args: [5] + }], + default: [{ + function: 'logAtag', + args: { analyticsValue: 'default-allow' } + }], + rules: [{ + conditions: ['true'], + results: [{ + function: 'excludeBidders', + args: [{ + bidders: ['bidder1'], + analyticsValue: 'excluded' + }] + }] + }] + }] + }] + }; + + sandbox.stub(Math, 'random').returns(0.5); + const auctionId = 'test-auction-id'; + rulesModule.evaluateConfig(rulesJson, auctionId); + + const bidder1Params = activityParams(MODULE_TYPE_BIDDER, 'bidder1', { + auctionId + }); + + expect(isActivityAllowed(ACTIVITY_FETCH_BIDS, bidder1Params)).to.be.true; + + expect(setLabelsStub.calledWith({ [auctionId + '-testAnalyticsKey']: 'default-allow' })).to.be.true; + + setLabelsStub.resetHistory(); + }); + }); + + describe('getGlobalRandom', function() { + it('should return the same value for the same auctionId and call Math.random only once', function() { + const auctionId = 'test-auction-id'; + const otherAuctionId = 'other-auction-id'; + const mathRandomStub = sandbox.stub(Math, 'random').returns(0.42); + const auction1 = { auctionId: auctionId }; + const auction2 = { auctionId: otherAuctionId }; + const auctions = { + [auctionId]: auction1, + [otherAuctionId]: auction2 + } + + const index = { + getAuction: ({ auctionId }) => auctions[auctionId] + } + + const result1 = rulesModule.dep.getGlobalRandom(auctionId, index); + const result2 = rulesModule.dep.getGlobalRandom(auctionId, index); + const result3 = rulesModule.dep.getGlobalRandom(auctionId, index); + + expect(result1).to.equal(0.42); + expect(result2).to.equal(0.42); + expect(result3).to.equal(0.42); + expect(mathRandomStub.calledOnce).to.equal(true); + + mathRandomStub.returns(0.99); + const result4 = rulesModule.dep.getGlobalRandom(otherAuctionId, index); + + expect(result4).to.equal(0.99); + expect(mathRandomStub.calledTwice).to.equal(true); + }); + }); + + describe('evaluateSchema', function() { + it('should evaluate percent condition', function() { + sandbox.stub(rulesModule.dep, 'getGlobalRandom').returns(0.3); + const func = rulesModule.evaluateSchema('percent', [50], {}); + const result = func(); + // 30 < 50, so should return true + expect(result).to.be.true; + }); + + it('should evaluate adUnitCode condition', function() { + const context = { + adUnit: { + code: 'div-1' + } + }; + const func = rulesModule.evaluateSchema('adUnitCode', [], context); + expect(func()).to.equal('div-1'); + + const func2 = rulesModule.evaluateSchema('adUnitCode', [], context); + expect(func2()).to.equal('div-1'); + }); + + it('should evaluate adUnitCodeIn condition', function() { + const context = { + adUnit: { + code: 'div-1' + } + }; + const func = rulesModule.evaluateSchema('adUnitCodeIn', [['div-1', 'div-2']], context); + expect(func()).to.be.true; + + const func2 = rulesModule.evaluateSchema('adUnitCodeIn', [['div-3', 'div-4']], context); + expect(func2()).to.be.false; + }); + + it('should evaluate deviceCountry condition', function() { + const context = { + ortb2: { + device: { + geo: { + country: 'US' + } + } + } + }; + const func = rulesModule.evaluateSchema('deviceCountry', [], context); + expect(func()).to.equal('US'); + + const func2 = rulesModule.evaluateSchema('deviceCountry', [], context); + expect(func2()).to.equal('US'); + }); + + it('should evaluate deviceCountryIn condition', function() { + const context = { + ortb2: { + device: { + geo: { + country: 'US' + } + } + } + }; + const func = rulesModule.evaluateSchema('deviceCountryIn', [['US', 'UK']], context); + expect(func()).to.be.true; + + const func2 = rulesModule.evaluateSchema('deviceCountryIn', [['DE', 'FR']], context); + expect(func2()).to.be.false; + }); + + it('should evaluate channel condition', function() { + const context1 = { + ortb2: { + ext: { + prebid: { + channel: 'pbjs' + } + } + } + }; + const func1 = rulesModule.evaluateSchema('channel', [], context1); + expect(func1()).to.equal('web'); + }); + + it('should evaluate eidAvailable condition', function() { + const context1 = { + ortb2: { + user: { + eids: [{ source: 'test', id: '123' }] + } + } + }; + const func1 = rulesModule.evaluateSchema('eidAvailable', [], context1); + expect(func1()).to.be.true; + + const context2 = { + ortb2: { + user: { + eids: [] + } + } + }; + const func2 = rulesModule.evaluateSchema('eidAvailable', [], context2); + expect(func2()).to.be.false; + }); + + it('should evaluate userFpdAvailable condition', function() { + const context1 = { + ortb2: { + user: { + data: [{ name: 'test', segment: [] }] + } + } + }; + const func1 = rulesModule.evaluateSchema('userFpdAvailable', [], context1); + expect(func1()).to.be.true; + + const context2 = { + ortb2: { + user: { + ext: { + data: [{ name: 'test', segment: [] }] + } + } + } + }; + const func2 = rulesModule.evaluateSchema('userFpdAvailable', [], context2); + expect(func2()).to.be.true; + + const context3 = { + ortb2: { + user: {} + } + }; + const func3 = rulesModule.evaluateSchema('userFpdAvailable', [], context3); + expect(func3()).to.be.false; + }); + + it('should evaluate fpdAvailable condition', function() { + const context1 = { + ortb2: { + user: { + data: [{ name: 'test' }] + } + } + }; + const func1 = rulesModule.evaluateSchema('fpdAvailable', [], context1); + expect(func1()).to.be.true; + + const context2 = { + ortb2: { + site: { + content: { + data: [{ name: 'test' }] + } + } + } + }; + const func2 = rulesModule.evaluateSchema('fpdAvailable', [], context2); + expect(func2()).to.be.true; + + const context3 = { + ortb2: {} + }; + const func3 = rulesModule.evaluateSchema('fpdAvailable', [], context3); + expect(func3()).to.be.false; + }); + + it('should evaluate gppSidIn condition', function() { + const context1 = { + ortb2: { + regs: { + gpp_sid: [1, 2, 3] + } + } + }; + const func1 = rulesModule.evaluateSchema('gppSidIn', [[2]], context1); + expect(func1()).to.be.true; + + const func2 = rulesModule.evaluateSchema('gppSidIn', [[4]], context1); + expect(func2()).to.be.false; + }); + + it('should evaluate tcfInScope condition', function() { + const context1 = { + ortb2: { + regs: { + ext: { + gdpr: 1 + } + } + } + }; + const func1 = rulesModule.evaluateSchema('tcfInScope', [], context1); + expect(func1()).to.be.true; + + const context2 = { + regs: { + ext: { + gdpr: 0 + } + } + }; + const func2 = rulesModule.evaluateSchema('tcfInScope', [], context2); + expect(func2()).to.be.false; + }); + + it('should evaluate domain condition', function() { + const context1 = { + ortb2: { + site: { + domain: 'example.com' + } + } + }; + const func1 = rulesModule.evaluateSchema('domain', [], context1); + expect(func1()).to.equal('example.com'); + + const context2 = { + ortb2: { + app: { + domain: 'app.example.com' + } + } + }; + const func2 = rulesModule.evaluateSchema('domain', [], context2); + expect(func2()).to.equal('app.example.com'); + + const context3 = { + ortb2: {} + }; + const func3 = rulesModule.evaluateSchema('domain', [], context3); + expect(func3()).to.equal(''); + }); + + it('should evaluate domainIn condition', function() { + const context1 = { + ortb2: { + site: { + domain: 'example.com' + } + } + }; + const func1 = rulesModule.evaluateSchema('domainIn', [['example.com', 'test.com']], context1); + expect(func1()).to.be.true; + + const context2 = { + ortb2: { + app: { + domain: 'app.example.com' + } + } + }; + const func2 = rulesModule.evaluateSchema('domainIn', [['app.example.com']], context2); + expect(func2()).to.be.true; + + const func3 = rulesModule.evaluateSchema('domainIn', [['other.com']], context1); + expect(func3()).to.be.false; + }); + + it('should evaluate bundle condition', function() { + const context1 = { + ortb2: { + app: { + bundle: 'com.example.app' + } + } + }; + const func1 = rulesModule.evaluateSchema('bundle', [], context1); + expect(func1()).to.equal('com.example.app'); + + const context2 = { + ortb2: {} + }; + const func2 = rulesModule.evaluateSchema('bundle', [], context2); + expect(func2()).to.equal(''); + }); + + it('should evaluate bundleIn condition', function() { + const context1 = { + ortb2: { + app: { + bundle: 'com.example.app' + } + } + }; + const func1 = rulesModule.evaluateSchema('bundleIn', ['com.example.app'], context1); + expect(func1()).to.be.true; + + const func2 = rulesModule.evaluateSchema('bundleIn', [['com.other.app']], context1); + expect(func2()).to.be.false; + }); + + it('should evaluate mediaTypeIn condition', function() { + const context1 = { + adUnit: { + mediaTypes: { + banner: {}, + video: {} + } + } + }; + const func1 = rulesModule.evaluateSchema('mediaTypeIn', [['banner']], context1); + expect(func1()).to.be.true; + + const func2 = rulesModule.evaluateSchema('mediaTypeIn', [['native']], context1); + expect(func2()).to.be.false; + }); + + it('should evaluate deviceTypeIn condition', function() { + const context1 = { + ortb2: { + device: { + devicetype: 2 + } + } + }; + const func1 = rulesModule.evaluateSchema('deviceTypeIn', [[2, 3]], context1); + expect(func1()).to.be.true; + + const func2 = rulesModule.evaluateSchema('deviceTypeIn', [[4, 5]], context1); + expect(func2()).to.be.false; + }); + + it('should evaluate bidPrice condition', function() { + const context1 = { + bid: { + cpm: 5.50, + currency: 'USD' + } + }; + const func1 = rulesModule.evaluateSchema('bidPrice', ['gt', 'USD', 5.0], context1); + expect(func1()).to.be.true; + + const func2 = rulesModule.evaluateSchema('bidPrice', ['gt', 'USD', 6.0], context1); + expect(func2()).to.be.false; + + const func3 = rulesModule.evaluateSchema('bidPrice', ['lte', 'USD', 6.0], context1); + expect(func3()).to.be.true; + + const context3 = { + bid: { + cpm: 0, + currency: 'USD' + } + }; + const func4 = rulesModule.evaluateSchema('bidPrice', ['gt', 'USD', 1.0], context3); + expect(func4()).to.be.false; + }); + + it('should return null function for unknown schema function', function() { + const func = rulesModule.evaluateSchema('unknownFunction', [], {}); + expect(func()).to.be.null; + }); + + describe('extraSchemaEvaluators', function() { + it('should use custom browser evaluator from extraSchemaEvaluators', function() { + const browserEvaluator = (args, context) => { + return () => { + const userAgent = context.ortb2?.device?.ua || navigator.userAgent; + if (userAgent.includes('Chrome')) return 'Chrome'; + if (userAgent.includes('Firefox')) return 'Firefox'; + if (userAgent.includes('Safari')) return 'Safari'; + if (userAgent.includes('Edge')) return 'Edge'; + return 'Unknown'; + }; + }; + + config.setConfig({ + shapingRules: { + extraSchemaEvaluators: { + browser: browserEvaluator + } + } + }); + + const context1 = { + ortb2: { + device: { + ua: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 Chrome/120.0.0.0' + } + } + }; + + const func1 = rulesModule.evaluateSchema('browser', [], context1); + expect(func1()).to.equal('Chrome'); + + const context2 = { + ortb2: { + device: { + ua: 'Mozilla/5.0 Firefox/121.0.0' + } + } + }; + const func2 = rulesModule.evaluateSchema('browser', [], context2); + expect(func2()).to.equal('Firefox'); + }); + }); + }); +}); diff --git a/test/spec/modules/rumbleBidAdapter_spec.js b/test/spec/modules/rumbleBidAdapter_spec.js index a3e34e34d20..b60fd1ca90b 100644 --- a/test/spec/modules/rumbleBidAdapter_spec.js +++ b/test/spec/modules/rumbleBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {spec, converter} from 'modules/rumbleBidAdapter.js'; +import { spec, converter } from 'modules/rumbleBidAdapter.js'; import { config } from '../../../src/config.js'; -import {BANNER} from "../../../src/mediaTypes.js"; -import {deepClone, getUniqueIdentifierStr} from "../../../src/utils.js"; -import {expect} from "chai"; +import { BANNER } from "../../../src/mediaTypes.js"; +import { deepClone, getUniqueIdentifierStr } from "../../../src/utils.js"; +import { expect } from "chai"; const bidder = 'rumble'; diff --git a/test/spec/modules/s2sTesting_spec.js b/test/spec/modules/s2sTesting_spec.js index 273f6747e52..bac8d7013e3 100644 --- a/test/spec/modules/s2sTesting_spec.js +++ b/test/spec/modules/s2sTesting_spec.js @@ -18,57 +18,57 @@ describe('s2sTesting', function () { }); it('returns undefined if no weights', function () { - expect(getExpectedSource(0, {server: 0, client: 0})).to.be.undefined; - expect(getExpectedSource(0.5, {client: 0})).to.be.undefined; + expect(getExpectedSource(0, { server: 0, client: 0 })).to.be.undefined; + expect(getExpectedSource(0.5, { client: 0 })).to.be.undefined; }); it('gets the expected source from 3 sources', function () { var sources = ['server', 'client', 'both']; - expect(getExpectedSource(0, {server: 1, client: 1, both: 2}, sources)).to.equal('server'); - expect(getExpectedSource(0.2499999, {server: 1, client: 1, both: 2}, sources)).to.equal('server'); - expect(getExpectedSource(0.25, {server: 1, client: 1, both: 2}, sources)).to.equal('client'); - expect(getExpectedSource(0.49999, {server: 1, client: 1, both: 2}, sources)).to.equal('client'); - expect(getExpectedSource(0.5, {server: 1, client: 1, both: 2}, sources)).to.equal('both'); - expect(getExpectedSource(0.99999, {server: 1, client: 1, both: 2}, sources)).to.equal('both'); + expect(getExpectedSource(0, { server: 1, client: 1, both: 2 }, sources)).to.equal('server'); + expect(getExpectedSource(0.2499999, { server: 1, client: 1, both: 2 }, sources)).to.equal('server'); + expect(getExpectedSource(0.25, { server: 1, client: 1, both: 2 }, sources)).to.equal('client'); + expect(getExpectedSource(0.49999, { server: 1, client: 1, both: 2 }, sources)).to.equal('client'); + expect(getExpectedSource(0.5, { server: 1, client: 1, both: 2 }, sources)).to.equal('both'); + expect(getExpectedSource(0.99999, { server: 1, client: 1, both: 2 }, sources)).to.equal('both'); }); it('gets the expected source from 2 sources', function () { - expect(getExpectedSource(0, {server: 2, client: 3})).to.equal('server'); - expect(getExpectedSource(0.39999, {server: 2, client: 3})).to.equal('server'); - expect(getExpectedSource(0.4, {server: 2, client: 3})).to.equal('client'); - expect(getExpectedSource(0.9, {server: 2, client: 3})).to.equal('client'); + expect(getExpectedSource(0, { server: 2, client: 3 })).to.equal('server'); + expect(getExpectedSource(0.39999, { server: 2, client: 3 })).to.equal('server'); + expect(getExpectedSource(0.4, { server: 2, client: 3 })).to.equal('client'); + expect(getExpectedSource(0.9, { server: 2, client: 3 })).to.equal('client'); var sources = ['server', 'client', 'both']; - expect(getExpectedSource(0, {server: 2, client: 3}, sources)).to.equal('server'); - expect(getExpectedSource(0.39999, {server: 2, client: 3}, sources)).to.equal('server'); - expect(getExpectedSource(0.4, {server: 2, client: 3}, sources)).to.equal('client'); - expect(getExpectedSource(0.9, {server: 2, client: 3}, sources)).to.equal('client'); + expect(getExpectedSource(0, { server: 2, client: 3 }, sources)).to.equal('server'); + expect(getExpectedSource(0.39999, { server: 2, client: 3 }, sources)).to.equal('server'); + expect(getExpectedSource(0.4, { server: 2, client: 3 }, sources)).to.equal('client'); + expect(getExpectedSource(0.9, { server: 2, client: 3 }, sources)).to.equal('client'); }); it('gets the expected source from 1 source', function () { - expect(getExpectedSource(0, {client: 2})).to.equal('client'); - expect(getExpectedSource(0.5, {client: 2})).to.equal('client'); - expect(getExpectedSource(0.99999, {client: 2})).to.equal('client'); + expect(getExpectedSource(0, { client: 2 })).to.equal('client'); + expect(getExpectedSource(0.5, { client: 2 })).to.equal('client'); + expect(getExpectedSource(0.99999, { client: 2 })).to.equal('client'); }); it('ignores an invalid source', function () { - expect(getExpectedSource(0, {client: 2, cache: 2})).to.equal('client'); - expect(getExpectedSource(0.3333, {server: 1, cache: 1, client: 2})).to.equal('server'); - expect(getExpectedSource(0.34, {server: 1, cache: 1, client: 2})).to.equal('client'); + expect(getExpectedSource(0, { client: 2, cache: 2 })).to.equal('client'); + expect(getExpectedSource(0.3333, { server: 1, cache: 1, client: 2 })).to.equal('server'); + expect(getExpectedSource(0.34, { server: 1, cache: 1, client: 2 })).to.equal('client'); }); it('ignores order of sources', function () { var sources = ['server', 'client', 'both']; - expect(getExpectedSource(0, {client: 1, server: 1, both: 2}, sources)).to.equal('server'); - expect(getExpectedSource(0.2499999, {both: 2, client: 1, server: 1}, sources)).to.equal('server'); - expect(getExpectedSource(0.25, {client: 1, both: 2, server: 1}, sources)).to.equal('client'); - expect(getExpectedSource(0.49999, {server: 1, both: 2, client: 1}, sources)).to.equal('client'); - expect(getExpectedSource(0.5, {both: 2, server: 1, client: 1}, sources)).to.equal('both'); + expect(getExpectedSource(0, { client: 1, server: 1, both: 2 }, sources)).to.equal('server'); + expect(getExpectedSource(0.2499999, { both: 2, client: 1, server: 1 }, sources)).to.equal('server'); + expect(getExpectedSource(0.25, { client: 1, both: 2, server: 1 }, sources)).to.equal('client'); + expect(getExpectedSource(0.49999, { server: 1, both: 2, client: 1 }, sources)).to.equal('client'); + expect(getExpectedSource(0.5, { both: 2, server: 1, client: 1 }, sources)).to.equal('both'); }); it('accepts an array of sources', function () { - expect(getExpectedSource(0.3333, {second: 2, first: 1}, ['first', 'second'])).to.equal('first'); - expect(getExpectedSource(0.34, {second: 2, first: 1}, ['first', 'second'])).to.equal('second'); - expect(getExpectedSource(0.9999, {second: 2, first: 1}, ['first', 'second'])).to.equal('second'); + expect(getExpectedSource(0.3333, { second: 2, first: 1 }, ['first', 'second'])).to.equal('first'); + expect(getExpectedSource(0.34, { second: 2, first: 1 }, ['first', 'second'])).to.equal('second'); + expect(getExpectedSource(0.9999, { second: 2, first: 1 }, ['first', 'second'])).to.equal('second'); }); }); @@ -83,7 +83,7 @@ describe('s2sTesting', function () { it('sets one client bidder', function () { const s2sConfig = { bidders: ['rubicon'], - bidderControl: {rubicon: {bidSource: {server: 1, client: 1}}} + bidderControl: { rubicon: { bidSource: { server: 1, client: 1 } } } }; s2sTesting.calculateBidSources(s2sConfig); @@ -96,7 +96,7 @@ describe('s2sTesting', function () { it('sets one server bidder', function () { const s2sConfig = { bidders: ['rubicon'], - bidderControl: {rubicon: {bidSource: {server: 4, client: 1}}} + bidderControl: { rubicon: { bidSource: { server: 4, client: 1 } } } } s2sTesting.calculateBidSources(s2sConfig); expect(s2sTesting.getSourceBidderMap()).to.eql({ @@ -120,8 +120,8 @@ describe('s2sTesting', function () { const s2sConfig = { bidders: ['rubicon', 'appnexus'], bidderControl: { - rubicon: {bidSource: {server: 3, client: 1}}, - appnexus: {bidSource: {server: 1, client: 1}} + rubicon: { bidSource: { server: 3, client: 1 } }, + appnexus: { bidSource: { server: 1, client: 1 } } } } s2sTesting.calculateBidSources(s2sConfig); @@ -136,8 +136,8 @@ describe('s2sTesting', function () { const s2sConfig = { bidders: ['rubicon', 'appnexus'], bidderControl: { - rubicon: {bidSource: {server: 1, client: 99}}, - appnexus: {bidSource: {server: 1, client: 99}} + rubicon: { bidSource: { server: 1, client: 99 } }, + appnexus: { bidSource: { server: 1, client: 99 } } } } s2sTesting.calculateBidSources(s2sConfig); @@ -159,8 +159,8 @@ describe('s2sTesting', function () { const s2sConfig2 = { bidders: ['rubicon', 'appnexus'], bidderControl: { - rubicon: {bidSource: {server: 99, client: 1}}, - appnexus: {bidSource: {server: 99, client: 1}} + rubicon: { bidSource: { server: 99, client: 1 } }, + appnexus: { bidSource: { server: 99, client: 1 } } } } s2sTesting.calculateBidSources(s2sConfig2); @@ -180,7 +180,7 @@ describe('s2sTesting', function () { }); describe('setting source through adUnits', function () { - const s2sConfig3 = {testing: true}; + const s2sConfig3 = { testing: true }; beforeEach(function () { // set random number for testing @@ -190,9 +190,11 @@ describe('s2sTesting', function () { it('sets one bidder source from one adUnit', function () { var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 4, client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 4, client: 1 } } + ] + } ]; expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ @@ -204,9 +206,11 @@ describe('s2sTesting', function () { expect(adUnits[0].bids[0].finalSource).to.equal('server'); adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 1, client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 1, client: 1 } } + ] + } ]; expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ server: [], @@ -219,9 +223,11 @@ describe('s2sTesting', function () { it('defaults to client if no bidSource', function () { var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: {} } + ] + } ]; expect(s2sTesting.getSourceBidderMap(adUnits, [])).to.eql({ server: [], @@ -234,10 +240,12 @@ describe('s2sTesting', function () { it('sets multiple bidders sources from one adUnit', function () { var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 2, client: 1}}, - {bidder: 'appnexus', bidSource: {server: 3, client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 2, client: 1 } }, + { bidder: 'appnexus', bidSource: { server: 3, client: 1 } } + ] + } ]; var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); expect(serverClientBidders.server).to.eql(['appnexus']); @@ -251,14 +259,18 @@ describe('s2sTesting', function () { it('sets multiple bidders sources from multiple adUnits', function () { var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 2, client: 1}}, - {bidder: 'appnexus', bidSource: {server: 1, client: 1}} - ]}, - {bids: [ - {bidder: 'rubicon', bidSource: {server: 4, client: 1}}, - {bidder: 'bidder3', bidSource: {client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 2, client: 1 } }, + { bidder: 'appnexus', bidSource: { server: 1, client: 1 } } + ] + }, + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 4, client: 1 } }, + { bidder: 'bidder3', bidSource: { client: 1 } } + ] + } ]; var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); expect(serverClientBidders.server).to.have.members(['rubicon']); @@ -277,11 +289,13 @@ describe('s2sTesting', function () { it('should reuse calculated sources', function () { var adUnits = [ - {bids: [ - {bidder: 'rubicon', calcSource: 'client', bidSource: {server: 4, client: 1}}, - {bidder: 'appnexus', calcSource: 'server', bidSource: {server: 1, client: 1}}, - {bidder: 'bidder3', calcSource: 'server', bidSource: {client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', calcSource: 'client', bidSource: { server: 4, client: 1 } }, + { bidder: 'appnexus', calcSource: 'server', bidSource: { server: 1, client: 1 } }, + { bidder: 'bidder3', calcSource: 'server', bidSource: { client: 1 } } + ] + } ]; var serverClientBidders = s2sTesting.getSourceBidderMap(adUnits, []); @@ -308,10 +322,12 @@ describe('s2sTesting', function () { it('should get sources from both', function () { // set rubicon: server and appnexus: client var adUnits = [ - {bids: [ - {bidder: 'rubicon', bidSource: {server: 4, client: 1}}, - {bidder: 'appnexus', bidSource: {client: 1}} - ]} + { + bids: [ + { bidder: 'rubicon', bidSource: { server: 4, client: 1 } }, + { bidder: 'appnexus', bidSource: { client: 1 } } + ] + } ]; // set rubicon: client and appnexus: server @@ -319,8 +335,8 @@ describe('s2sTesting', function () { bidders: ['rubicon', 'appnexus'], testing: true, bidderControl: { - rubicon: {bidSource: {server: 2, client: 1}}, - appnexus: {bidSource: {server: 1}} + rubicon: { bidSource: { server: 2, client: 1 } }, + appnexus: { bidSource: { server: 1 } } } } s2sTesting.calculateBidSources(s2sConfig); diff --git a/test/spec/modules/scaleableAnalyticsAdapter_spec.js b/test/spec/modules/scaleableAnalyticsAdapter_spec.js index 5f86073894a..68944b56c1c 100644 --- a/test/spec/modules/scaleableAnalyticsAdapter_spec.js +++ b/test/spec/modules/scaleableAnalyticsAdapter_spec.js @@ -55,7 +55,7 @@ describe('Scaleable Analytics Adapter', function() { const bidObj = MOCK_DATA.bidderRequests[0].bids[0]; - const expectedBidRequests = [{bidder: 'scaleable_adunit_request'}].concat([ + const expectedBidRequests = [{ bidder: 'scaleable_adunit_request' }].concat([ { bidder: bidObj.bidder, params: bidObj.params diff --git a/test/spec/modules/scaliburBidAdapter_spec.js b/test/spec/modules/scaliburBidAdapter_spec.js index c2f6a3c65a8..98290963b1e 100644 --- a/test/spec/modules/scaliburBidAdapter_spec.js +++ b/test/spec/modules/scaliburBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec, getFirstPartyData, storage} from 'modules/scaliburBidAdapter.js'; +import { expect } from 'chai'; +import { spec, getFirstPartyData, storage } from 'modules/scaliburBidAdapter.js'; describe('Scalibur Adapter', function () { const BID = { @@ -62,7 +62,7 @@ describe('Scalibur Adapter', function () { ref: 'https://example-referrer.com', }, user: { - data: [{name: 'segments', segment: ['sports', 'entertainment']}], + data: [{ name: 'segments', segment: ['sports', 'entertainment'] }], }, regs: { ext: { @@ -118,7 +118,7 @@ describe('Scalibur Adapter', function () { }); it('should return false for missing placementId', function () { - const invalidBid = {...BID, params: {}}; + const invalidBid = { ...BID, params: {} }; expect(spec.isBidRequestValid(invalidBid)).to.equal(false); }); }); @@ -136,8 +136,8 @@ describe('Scalibur Adapter', function () { expect(imp.ext.placementId).to.equal('test-scl-placement'); expect(imp.ext.gpid).to.equal('/1234/5678/homepage'); expect(imp.banner.format).to.deep.equal([ - {w: 300, h: 250}, - {w: 728, h: 90}, + { w: 300, h: 250 }, + { w: 728, h: 90 }, ]); const video = imp.video; @@ -165,8 +165,8 @@ describe('Scalibur Adapter', function () { expect(imp.ext.placementId).to.equal('test-scl-placement'); expect(imp.ext.gpid).to.equal('/1234/5678/homepage'); expect(imp.banner.format).to.deep.equal([ - {w: 300, h: 250}, - {w: 728, h: 90}, + { w: 300, h: 250 }, + { w: 728, h: 90 }, ]); const video = imp.video; @@ -230,7 +230,7 @@ describe('Scalibur Adapter', function () { describe('getUserSyncs', function () { it('should return iframe and pixel sync URLs with correct params', function () { - const syncOptions = {iframeEnabled: true, pixelEnabled: true}; + const syncOptions = { iframeEnabled: true, pixelEnabled: true }; const gdprConsent = { gdprApplies: true, consentString: 'BOEFEAyOEFEAyAHABDENAI4AAAB9vABAASA', diff --git a/test/spec/modules/schain_spec.js b/test/spec/modules/schain_spec.js index 4517eb976fb..1b9e3fd2ece 100644 --- a/test/spec/modules/schain_spec.js +++ b/test/spec/modules/schain_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai/index.js'; +import { expect } from 'chai/index.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; -import {applySchainConfig} from 'modules/schain.js'; +import { config } from 'src/config.js'; +import { applySchainConfig } from 'modules/schain.js'; describe('Supply Chain fpd', function() { const SAMPLE_SCHAIN = { diff --git a/test/spec/modules/scope3RtdProvider_spec.js b/test/spec/modules/scope3RtdProvider_spec.js index 367d5823861..de1fc14646e 100644 --- a/test/spec/modules/scope3RtdProvider_spec.js +++ b/test/spec/modules/scope3RtdProvider_spec.js @@ -1,4 +1,4 @@ -import {auctionManager} from 'src/auctionManager.js'; +import { auctionManager } from 'src/auctionManager.js'; import { scope3SubModule } from 'modules/scope3RtdProvider.js'; import * as utils from 'src/utils.js'; import { server } from 'test/mocks/xhr.js'; @@ -584,7 +584,7 @@ describe('Scope3 RTD Module', function() { getFPD: () => { return reqBidsConfigObj.ortb2Fragments } }); - const targetingData = scope3SubModule.getTargetingData([ reqBidsConfigObj.adUnits[0].code ], config, {}, { adUnits: reqBidsConfigObj.adUnits }) + const targetingData = scope3SubModule.getTargetingData([reqBidsConfigObj.adUnits[0].code], config, {}, { adUnits: reqBidsConfigObj.adUnits }) expect(targetingData['test-ad-unit-nocache']).to.be.an('object') expect(targetingData['test-ad-unit-nocache']['axei']).to.be.an('array') expect(targetingData['test-ad-unit-nocache']['axei'].length).to.equal(1) diff --git a/test/spec/modules/screencoreBidAdapter_spec.js b/test/spec/modules/screencoreBidAdapter_spec.js index bd1aad95edf..c80998a4672 100644 --- a/test/spec/modules/screencoreBidAdapter_spec.js +++ b/test/spec/modules/screencoreBidAdapter_spec.js @@ -227,7 +227,7 @@ describe('screencore bid adapter', function () { const requests = adapter.buildRequests([BID], BIDDER_REQUEST); expect(requests).to.exist; expect(requests.method).to.equal('POST'); - expect(requests.url).to.include('screencore.io/prebid'); + expect(requests.url).to.include('screencore.io/pbjs'); expect(requests.data).to.exist; expect(requests.data.placements).to.be.an('array'); expect(requests.data.placements[0].bidId).to.equal(BID.bidId); @@ -394,5 +394,38 @@ describe('screencore bid adapter', function () { stub.restore(); }); + + it('should return correct domain for US/ prefixed timezone', function () { + const stub = sinon.stub(Intl, 'DateTimeFormat').returns({ + resolvedOptions: () => ({ timeZone: 'US/Eastern' }) + }); + + const domain = createDomain(); + expect(domain).to.equal('https://taqus.screencore.io'); + + stub.restore(); + }); + + it('should return correct domain for Canada/ prefixed timezone', function () { + const stub = sinon.stub(Intl, 'DateTimeFormat').returns({ + resolvedOptions: () => ({ timeZone: 'Canada/Eastern' }) + }); + + const domain = createDomain(); + expect(domain).to.equal('https://taqus.screencore.io'); + + stub.restore(); + }); + + it('should return EU domain as default for unknown timezone', function () { + const stub = sinon.stub(Intl, 'DateTimeFormat').returns({ + resolvedOptions: () => ({ timeZone: 'UTC' }) + }); + + const domain = createDomain(); + expect(domain).to.equal('https://taqeu.screencore.io'); + + stub.restore(); + }); }); }); diff --git a/test/spec/modules/seedingAllianceAdapter_spec.js b/test/spec/modules/seedingAllianceAdapter_spec.js index 52be0caeb82..3f62427a2f9 100755 --- a/test/spec/modules/seedingAllianceAdapter_spec.js +++ b/test/spec/modules/seedingAllianceAdapter_spec.js @@ -1,8 +1,8 @@ // jshint esversion: 6, es3: false, node: true -import {assert, expect} from 'chai'; -import {getStorageManager} from 'src/storageManager.js'; -import {spec} from 'modules/seedingAllianceBidAdapter.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { assert, expect } from 'chai'; +import { getStorageManager } from 'src/storageManager.js'; +import { spec } from 'modules/seedingAllianceBidAdapter.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('SeedingAlliance adapter', function () { let serverResponse, bidRequest, bidResponses; @@ -152,8 +152,8 @@ describe('SeedingAlliance adapter', function () { adm: JSON.stringify({ native: { assets: [ - {id: 0, title: {text: 'this is a title'}}, - {id: 1, img: {url: 'https://domain.for/img.jpg'}}, + { id: 0, title: { text: 'this is a title' } }, + { id: 1, img: { url: 'https://domain.for/img.jpg' } }, ], imptrackers: ['https://domain.for/imp/tracker?price=${AUCTION_PRICE}'], link: { @@ -189,20 +189,22 @@ describe('SeedingAlliance adapter', function () { } }; - const badResponse = { body: { - cur: 'EUR', - id: 'bidid1', - seatbid: [] - }}; + const badResponse = { + body: { + cur: 'EUR', + id: 'bidid1', + seatbid: [] + } + }; const bidNativeRequest = { data: {}, - bidRequests: [{bidId: '1', nativeParams: {title: {required: true, len: 800}, image: {required: true, sizes: [300, 250]}}}] + bidRequests: [{ bidId: '1', nativeParams: { title: { required: true, len: 800 }, image: { required: true, sizes: [300, 250] } } }] }; const bidBannerRequest = { data: {}, - bidRequests: [{bidId: '1', sizes: [300, 250]}] + bidRequests: [{ bidId: '1', sizes: [300, 250] }] }; it('should return null if body is missing or empty', function () { diff --git a/test/spec/modules/sevioBidAdapter_spec.js b/test/spec/modules/sevioBidAdapter_spec.js index 63b36465dad..56d25307532 100644 --- a/test/spec/modules/sevioBidAdapter_spec.js +++ b/test/spec/modules/sevioBidAdapter_spec.js @@ -133,7 +133,7 @@ describe('sevioBidAdapter', function () { 'ttl': 3000, 'ad': '

I am an ad

', 'mediaType': 'banner', - 'meta': {'advertiserDomains': ['none.com']} + 'meta': { 'advertiserDomains': ['none.com'] } }]; let result = spec.interpretResponse(serverResponse, bidRequest[0]); @@ -370,7 +370,8 @@ describe('sevioBidAdapter', function () { const original = perfTop.getEntriesByType; Object.defineProperty(perfTop, 'getEntriesByType', { - configurable: true, writable: true, + configurable: true, + writable: true, value: (type) => (type === 'navigation' ? [{ responseStart: 152, requestStart: 100 }] : []) }); @@ -521,4 +522,108 @@ describe('sevioBidAdapter', function () { expect(requests[0].data.keywords.tokens).to.deep.equal(['play', 'games', 'fun']); }); }); + + describe('native parsing', function () { + it('parses native assets: title, data->desc (type 2), image (asset.img), clickUrl and trackers', function () { + const serverResponseNative = { + body: { + bids: [ + { + requestId: 'native-1', + cpm: 1.0, + currency: 'EUR', + width: 1, + height: 1, + creativeId: 'native-creative-1', + ad: JSON.stringify({ + ver: '1.2', + assets: [ + { id: 2, title: { text: 'Native Title' } }, + { id: 4, data: { type: 2, value: 'Native body text' } }, + { id: 5, img: { type: 3, url: 'https://img.example/x.png', w: 120, h: 60 } } + ], + eventtrackers: [ + { event: 1, method: 1, url: 'https://impr.example/1' }, + { event: 2, method: 1, url: 'https://view.example/1' } + ], + link: { url: 'https://click.example', clicktrackers: ['https://clickt.example/1'] } + }), + ttl: 300, + netRevenue: true, + mediaType: 'NATIVE', + meta: { advertiserDomains: ['adv.example'] }, + bidder: 'sevio' + } + ] + } + }; + + const result = spec.interpretResponse(serverResponseNative); + expect(result).to.be.an('array').with.lengthOf(1); + + const out = result[0]; + expect(out).to.have.property('native'); + + const native = out.native; + expect(native.title).to.equal('Native Title'); + expect(native.image).to.equal('https://img.example/x.png'); + expect(native.image_width).to.equal(120); + expect(native.image_height).to.equal(60); + expect(native.clickUrl).to.equal('https://click.example'); + + expect(native.impressionTrackers).to.be.an('array').that.includes('https://impr.example/1'); + expect(native.viewableTrackers).to.be.an('array').that.includes('https://view.example/1'); + expect(native.clickTrackers).to.be.an('array').that.includes('https://clickt.example/1'); + + // meta preserved + expect(out.meta).to.have.property('advertiserDomains').that.deep.equals(['adv.example']); + }); + + it('maps legacy asset.id -> image types (13 -> icon, 14 -> image) and sets icon fields', function () { + const serverResponseIcon = { + body: { + bids: [ + { + requestId: 'native-icon', + cpm: 1.0, + currency: 'EUR', + width: 1, + height: 1, + creativeId: 'native-creative-icon', + ad: JSON.stringify({ + ver: '1.2', + assets: [ + // legacy asset id 13 should map to icon (img type 1) + { id: 13, img: { url: 'https://img.example/icon.png', w: 50, h: 50 } }, + // legacy asset id 14 should map to image (img type 3) + { id: 14, img: { url: 'https://img.example/img.png', w: 200, h: 100 } }, + { id: 2, title: { text: 'Legacy Mapping Test' } } + ], + link: { url: 'https://click.example/leg' } + }), + ttl: 300, + netRevenue: true, + mediaType: 'NATIVE', + meta: { advertiserDomains: ['legacy.example'] }, + bidder: 'sevio' + } + ] + } + }; + + const result = spec.interpretResponse(serverResponseIcon); + expect(result).to.be.an('array').with.lengthOf(1); + const native = result[0].native; + + // icon mapped from id 13 + expect(native.icon).to.equal('https://img.example/icon.png'); + expect(native.icon_width).to.equal(50); + expect(native.icon_height).to.equal(50); + + // image mapped from id 14 + expect(native.image).to.equal('https://img.example/img.png'); + expect(native.image_width).to.equal(200); + expect(native.image_height).to.equal(100); + }); + }); }); diff --git a/test/spec/modules/sharedIdSystem_spec.js b/test/spec/modules/sharedIdSystem_spec.js index c258e2ad4f7..7a4c9f9c5ab 100644 --- a/test/spec/modules/sharedIdSystem_spec.js +++ b/test/spec/modules/sharedIdSystem_spec.js @@ -1,11 +1,11 @@ -import {sharedIdSystemSubmodule} from 'modules/sharedIdSystem.js'; -import {config} from 'src/config.js'; +import { sharedIdSystemSubmodule } from 'modules/sharedIdSystem.js'; +import { config } from 'src/config.js'; import sinon from 'sinon'; import * as utils from 'src/utils.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const expect = require('chai').expect; @@ -51,7 +51,7 @@ describe('SharedId System', function () { expect(callbackSpy.lastCall.lastArg).to.equal(UUID); }); it('should abort if coppa is set', function () { - const result = sharedIdSystemSubmodule.getId({}, {coppa: true}); + const result = sharedIdSystemSubmodule.getId({}, { coppa: true }); expect(result).to.be.undefined; }); }); @@ -82,7 +82,7 @@ describe('SharedId System', function () { expect(pubcommId).to.equal('TestId'); }); it('should abort if coppa is set', function () { - const result = sharedIdSystemSubmodule.extendId({params: {extend: true}}, {coppa: true}, 'TestId'); + const result = sharedIdSystemSubmodule.extendId({ params: { extend: true } }, { coppa: true }, 'TestId'); expect(result).to.be.undefined; }); }); @@ -101,7 +101,7 @@ describe('SharedId System', function () { expect(newEids.length).to.equal(1); expect(newEids[0]).to.deep.equal({ source: 'pubcid.org', - uids: [{id: 'some-random-id-value', atype: 1}] + uids: [{ id: 'some-random-id-value', atype: 1 }] }); }); @@ -113,7 +113,7 @@ describe('SharedId System', function () { params: { inserter: 'mock-inserter' }, - value: {pubcid: 'mock-id'} + value: { pubcid: 'mock-id' } }] } }); diff --git a/test/spec/modules/shinezBidAdapter_spec.js b/test/spec/modules/shinezBidAdapter_spec.js index b5976fbc7d2..af912cbf079 100644 --- a/test/spec/modules/shinezBidAdapter_spec.js +++ b/test/spec/modules/shinezBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/shinezBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; import * as utils from 'src/utils.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; const ENDPOINT = 'https://hb.sweetgum.io/hb-sz-multi'; const TEST_ENDPOINT = 'https://hb.sweetgum.io/hb-multi-sz-test'; @@ -92,7 +92,7 @@ describe('shinezAdapter', function () { 'mediaTypes': { 'banner': { 'sizes': [ - [ 300, 250 ] + [300, 250] ] }, 'video': { @@ -284,7 +284,7 @@ describe('shinezAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -297,7 +297,7 @@ describe('shinezAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -305,7 +305,7 @@ describe('shinezAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); diff --git a/test/spec/modules/shinezRtbBidAdapter_spec.js b/test/spec/modules/shinezRtbBidAdapter_spec.js index 2dd33d7ef5b..603c6dee835 100644 --- a/test/spec/modules/shinezRtbBidAdapter_spec.js +++ b/test/spec/modules/shinezRtbBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, @@ -14,12 +14,12 @@ import { tryParseJSON, getUniqueDealId, } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {parseUrl, deepClone, getWinDimensions} from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { parseUrl, deepClone, getWinDimensions } from 'src/utils.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; import * as utils from 'src/utils.js'; export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -104,9 +104,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -123,7 +123,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -196,9 +196,8 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, - "site": {"content": {"language": "en"} - } + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, + "site": { "content": { "language": "en" } } }; const REQUEST = { @@ -211,7 +210,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -333,9 +332,9 @@ describe('ShinezRtbBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -407,9 +406,9 @@ describe('ShinezRtbBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -454,7 +453,7 @@ describe('ShinezRtbBidAdapter', function () { }); describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -463,7 +462,7 @@ describe('ShinezRtbBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.sweetgum.io/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -471,7 +470,7 @@ describe('ShinezRtbBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.sweetgum.io/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -483,7 +482,7 @@ describe('ShinezRtbBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.sweetgum.io/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -498,12 +497,12 @@ describe('ShinezRtbBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -576,9 +575,9 @@ describe('ShinezRtbBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -599,7 +598,7 @@ describe('ShinezRtbBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -610,11 +609,11 @@ describe('ShinezRtbBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -629,7 +628,7 @@ describe('ShinezRtbBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -644,11 +643,11 @@ describe('ShinezRtbBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -661,18 +660,18 @@ describe('ShinezRtbBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -732,7 +731,7 @@ describe('ShinezRtbBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -748,8 +747,8 @@ describe('ShinezRtbBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/showheroes-bsBidAdapter_spec.js b/test/spec/modules/showheroes-bsBidAdapter_spec.js index 290447c3792..42e6626436a 100644 --- a/test/spec/modules/showheroes-bsBidAdapter_spec.js +++ b/test/spec/modules/showheroes-bsBidAdapter_spec.js @@ -117,19 +117,19 @@ describe('shBidAdapter', () => { bids: [bidRequestVideoV2], ...bidderRequest, ...gdpr, - ...{uspConsent: uspConsent}, + ...{ uspConsent: uspConsent }, ortb2: { source: { - ext: {schain: schain.schain.config} + ext: { schain: schain.schain.config } } } }; bidRequest.ortb2 = { source: { - ext: {schain: schain.schain.config} + ext: { schain: schain.schain.config } } }; - const getFloorResponse = {currency: 'EUR', floor: 3}; + const getFloorResponse = { currency: 'EUR', floor: 3 }; bidRequest.getFloor = () => getFloorResponse; const request = spec.buildRequests([bidRequest], await addFPDToBidderRequest(fullRequest)); const payload = request.data; diff --git a/test/spec/modules/silvermobBidAdapter_spec.js b/test/spec/modules/silvermobBidAdapter_spec.js index 21cdea24d18..a592396cc8b 100644 --- a/test/spec/modules/silvermobBidAdapter_spec.js +++ b/test/spec/modules/silvermobBidAdapter_spec.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import {spec} from '../../../modules/silvermobBidAdapter.js'; +import { spec } from '../../../modules/silvermobBidAdapter.js'; import 'modules/priceFloors.js'; import { newBidder } from 'src/adapters/bidderFactory'; import { config } from '../../../src/config.js'; @@ -181,7 +181,7 @@ describe('silvermobAdapter', function () { }); it('should send the CCPA data in the request', async function () { - const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({...bidderRequest, ...{uspConsent: '1YYY'}})); + const serverRequest = spec.buildRequests([SIMPLE_BID_REQUEST], await addFPDToBidderRequest({ ...bidderRequest, ...{ uspConsent: '1YYY' } })); expect(serverRequest.data.regs.ext.us_privacy).to.equal('1YYY'); }); }); diff --git a/test/spec/modules/sirdataRtdProvider_spec.js b/test/spec/modules/sirdataRtdProvider_spec.js index da7c8756cc8..4eb28b52b26 100644 --- a/test/spec/modules/sirdataRtdProvider_spec.js +++ b/test/spec/modules/sirdataRtdProvider_spec.js @@ -13,11 +13,11 @@ import { setUidInStorage, sirdataSubmodule } from 'modules/sirdataRtdProvider.js'; -import {expect} from 'chai'; -import {deepSetValue} from 'src/utils.js'; -import {server} from 'test/mocks/xhr.js'; +import { expect } from 'chai'; +import { deepSetValue } from 'src/utils.js'; +import { server } from 'test/mocks/xhr.js'; -const responseHeader = {'Content-Type': 'application/json'}; +const responseHeader = { 'Content-Type': 'application/json' }; describe('sirdataRtdProvider', function () { describe('sirdata Submodule init', function () { @@ -62,16 +62,16 @@ describe('sirdataRtdProvider', function () { it('sets Id in Storage', function () { setUidInStorage('123456789'); const val = getUidFromStorage(); - expect(val).to.deep.equal([{source: 'sddan.com', uids: [{id: '123456789', atype: 1}]}]); + expect(val).to.deep.equal([{ source: 'sddan.com', uids: [{ id: '123456789', atype: 1 }] }]); }); }); describe('mergeEuidsArrays', function () { it('merges Euids Arrays', function () { - const object1 = [{source: 'sddan.com', uids: [{id: '123456789', atype: 1}]}]; - const object2 = [{source: 'sddan.com', uids: [{id: '987654321', atype: 1}]}]; + const object1 = [{ source: 'sddan.com', uids: [{ id: '123456789', atype: 1 }] }]; + const object2 = [{ source: 'sddan.com', uids: [{ id: '987654321', atype: 1 }] }]; const object3 = mergeEuidsArrays(object1, object2); - expect(object3).to.deep.equal([{source: 'sddan.com', uids: [{id: '123456789', atype: 1}, {id: '987654321', atype: 1}]}]); + expect(object3).to.deep.equal([{ source: 'sddan.com', uids: [{ id: '123456789', atype: 1 }, { id: '987654321', atype: 1 }] }]); }); }); @@ -156,7 +156,7 @@ describe('sirdataRtdProvider', function () { const firstData = { segments: [111111, 222222], - contextual_categories: {'333333': 100}, + contextual_categories: { '333333': 100 }, 'segtaxid': null, 'cattaxid': null, 'shared_taxonomy': { @@ -164,7 +164,7 @@ describe('sirdataRtdProvider', function () { 'segments': [444444, 555555], 'segtaxid': null, 'cattaxid': null, - 'contextual_categories': {'666666': 100} + 'contextual_categories': { '666666': 100 } } }, 'global_taxonomy': { @@ -172,7 +172,7 @@ describe('sirdataRtdProvider', function () { 'segments': [123, 234], 'segtaxid': 4, 'cattaxid': 7, - 'contextual_categories': {'345': 100, '456': 100} + 'contextual_categories': { '345': 100, '456': 100 } }, 'sddan_id': '123456789', 'post_content_token': '987654321' @@ -231,20 +231,20 @@ describe('sirdataRtdProvider', function () { } }, { bidder: 'proxistore', - params: {website: 'demo.sirdata.com', language: 'fr'}, + params: { website: 'demo.sirdata.com', language: 'fr' }, adUnitCode: 'HALFPAGE_CENTER_LOADER', transactionId: '92ac333a-a569-4827-abf1-01fc9d19278a', sizes: [[300, 600]], mediaTypes: { banner: { filteredSizeConfig: [ - {minViewPort: [1600, 0], sizes: [[300, 600]]}, + { minViewPort: [1600, 0], sizes: [[300, 600]] }, ], sizeConfig: [ - {minViewPort: [0, 0], sizes: [[300, 600]]}, - {minViewPort: [768, 0], sizes: [[300, 600]]}, - {minViewPort: [1200, 0], sizes: [[300, 600]]}, - {minViewPort: [1600, 0], sizes: [[300, 600]]}, + { minViewPort: [0, 0], sizes: [[300, 600]] }, + { minViewPort: [768, 0], sizes: [[300, 600]] }, + { minViewPort: [1200, 0], sizes: [[300, 600]] }, + { minViewPort: [1600, 0], sizes: [[300, 600]] }, ], sizes: [[300, 600]], }, @@ -280,19 +280,19 @@ describe('sirdataRtdProvider', function () { 'segments': [111111, 222222], 'segtaxid': null, 'cattaxid': null, - 'contextual_categories': {'333333': 100}, + 'contextual_categories': { '333333': 100 }, 'shared_taxonomy': { '27440': { 'segments': [444444, 555555], 'segtaxid': 552, 'cattaxid': 553, - 'contextual_categories': {'666666': 100} + 'contextual_categories': { '666666': 100 } }, '27446': { 'segments': [777777, 888888], 'segtaxid': 552, 'cattaxid': 553, - 'contextual_categories': {'999999': 100} + 'contextual_categories': { '999999': 100 } } }, 'global_taxonomy': { @@ -300,7 +300,7 @@ describe('sirdataRtdProvider', function () { 'segments': [123, 234], 'segtaxid': 4, 'cattaxid': 7, - 'contextual_categories': {'345': 100, '456': 100} + 'contextual_categories': { '345': 100, '456': 100 } } }, 'sddan_id': '123456789', @@ -317,8 +317,8 @@ describe('sirdataRtdProvider', function () { 'sirdata.com' ); expect(reqBidsConfigObj.ortb2Fragments.global.site.content.data[0].segment).to.eql([ - {id: '345'}, - {id: '456'} + { id: '345' }, + { id: '456' } ]); expect(reqBidsConfigObj.ortb2Fragments.global.site.content.data[0].ext.segtax).to.equal(7); @@ -326,8 +326,8 @@ describe('sirdataRtdProvider', function () { 'sirdata.com' ); expect(reqBidsConfigObj.ortb2Fragments.global.user.data[0].segment).to.eql([ - {id: '123'}, - {id: '234'} + { id: '123' }, + { id: '234' } ]); expect(reqBidsConfigObj.ortb2Fragments.global.user.data[0].ext.segtax).to.equal(4); }); diff --git a/test/spec/modules/sizeMappingV2_spec.js b/test/spec/modules/sizeMappingV2_spec.js index b384e21debe..0e192e366e5 100644 --- a/test/spec/modules/sizeMappingV2_spec.js +++ b/test/spec/modules/sizeMappingV2_spec.js @@ -650,7 +650,7 @@ describe('sizeMappingV2', function () { }, native: {} }, - bids: [{bidder: 'appnexus', params: 1234}] + bids: [{ bidder: 'appnexus', params: 1234 }] }]; checkAdUnitSetupHook(adUnit); @@ -672,7 +672,7 @@ describe('sizeMappingV2', function () { }, native: {} }, - bids: [{bidder: 'appnexus', params: 1234}] + bids: [{ bidder: 'appnexus', params: 1234 }] }]; checkAdUnitSetupHook(adUnit); @@ -691,7 +691,7 @@ describe('sizeMappingV2', function () { mediaTypes: { native: {} }, - bids: [{bidder: 'appnexus', params: 1234}] + bids: [{ bidder: 'appnexus', params: 1234 }] }]; checkAdUnitSetupHook(adUnit); @@ -1456,7 +1456,7 @@ describe('sizeMappingV2', function () { adUnitDetail.transformedMediaTypes.native = {}; const actual = setupAdUnitMediaTypes(adUnits, [])[0]; const bids = bidderMap(actual); - expect(bids.rubicon.mediaTypes).to.deep.equal({banner: adUnitDetail.transformedMediaTypes.banner}); + expect(bids.rubicon.mediaTypes).to.deep.equal({ banner: adUnitDetail.transformedMediaTypes.banner }); }); }); }); diff --git a/test/spec/modules/sizeMapping_spec.js b/test/spec/modules/sizeMapping_spec.js index 795e87e72f5..2b2bbd3ab0e 100644 --- a/test/spec/modules/sizeMapping_spec.js +++ b/test/spec/modules/sizeMapping_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {resolveStatus, setSizeConfig, sizeSupported} from 'modules/sizeMapping.js'; +import { expect } from 'chai'; +import { resolveStatus, setSizeConfig, sizeSupported } from 'modules/sizeMapping.js'; const utils = require('src/utils.js'); const deepClone = utils.deepClone; @@ -51,7 +51,7 @@ describe('sizeMapping', function () { sandbox = sinon.createSandbox(); - matchMediaOverride = {matches: false}; + matchMediaOverride = { matches: false }; sandbox.stub(utils.getWindowTop(), 'matchMedia').callsFake((...args) => { if (typeof matchMediaOverride === 'function') { @@ -69,7 +69,7 @@ describe('sizeMapping', function () { describe('sizeConfig', () => { it('should allow us to validate a single size', function () { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 1200px)' ? { matches: true } : { matches: false }; expect(sizeSupported([300, 250])).to.equal(true); expect(sizeSupported([80, 80])).to.equal(false); @@ -122,11 +122,11 @@ describe('sizeMapping', function () { } } } - Object.entries(suites).forEach(([mediaType, {mediaTypes, getSizes}]) => { + Object.entries(suites).forEach(([mediaType, { mediaTypes, getSizes }]) => { describe(`for ${mediaType}`, () => { describe('when handling sizes', function () { it('when one mediaQuery block matches, it should filter the adUnit.sizes passed in', function () { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 1200px)' ? { matches: true } : { matches: false }; const status = resolveStatus(undefined, mediaTypes, sizeConfig); @@ -140,7 +140,7 @@ describe('sizeMapping', function () { matchMediaOverride = (str) => [ '(min-width: 1200px)', '(min-width: 768px) and (max-width: 1199px)' - ].includes(str) ? {matches: true} : {matches: false}; + ].includes(str) ? { matches: true } : { matches: false }; const status = resolveStatus(undefined, mediaTypes, sizeConfig); expect(status.active).to.equal(true); @@ -150,7 +150,7 @@ describe('sizeMapping', function () { }); it('if no mediaQueries match, it should allow all sizes specified', function () { - matchMediaOverride = () => ({matches: false}); + matchMediaOverride = () => ({ matches: false }); const status = resolveStatus(undefined, mediaTypes, sizeConfig); expect(status.active).to.equal(true); @@ -158,7 +158,7 @@ describe('sizeMapping', function () { }); it('if a mediaQuery matches and has sizesSupported: [], it should filter all sizes', function () { - matchMediaOverride = (str) => str === '(min-width: 0px) and (max-width: 767px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 0px) and (max-width: 767px)' ? { matches: true } : { matches: false }; const status = resolveStatus(undefined, mediaTypes, sizeConfig); expect(status.active).to.equal(false); @@ -166,7 +166,7 @@ describe('sizeMapping', function () { }); it('should filter all banner sizes and should disable the adUnit even if other mediaTypes are present', function () { - matchMediaOverride = (str) => str === '(min-width: 0px) and (max-width: 767px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 0px) and (max-width: 767px)' ? { matches: true } : { matches: false }; const status = resolveStatus(undefined, Object.assign({}, mediaTypes, { native: { type: 'image' @@ -180,7 +180,7 @@ describe('sizeMapping', function () { }); it('if a mediaQuery matches and no sizesSupported specified, it should not affect adUnit.sizes', function () { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 1200px)' ? { matches: true } : { matches: false }; const status = resolveStatus(undefined, mediaTypes, sizeConfigWithLabels); expect(status.active).to.equal(true); @@ -190,7 +190,7 @@ describe('sizeMapping', function () { describe('when handling labels', function () { it('should activate/deactivate adUnits/bidders based on sizeConfig.labels', function () { - matchMediaOverride = (str) => str === '(min-width: 1200px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 1200px)' ? { matches: true } : { matches: false }; let status = resolveStatus({ labels: ['desktop'] @@ -252,7 +252,7 @@ describe('sizeMapping', function () { if (FEATURES.VIDEO) { it('should activate/decactivate adUnits/bidders based on labels with multiformat ads', function () { - matchMediaOverride = (str) => str === '(min-width: 768px) and (max-width: 1199px)' ? {matches: true} : {matches: false}; + matchMediaOverride = (str) => str === '(min-width: 768px) and (max-width: 1199px)' ? { matches: true } : { matches: false }; const multiFormatSizes = { banner: { diff --git a/test/spec/modules/smaatoBidAdapter_spec.js b/test/spec/modules/smaatoBidAdapter_spec.js index f1bd464fbdd..50e48e69fd8 100644 --- a/test/spec/modules/smaatoBidAdapter_spec.js +++ b/test/spec/modules/smaatoBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {spec} from 'modules/smaatoBidAdapter.js'; +import { spec } from 'modules/smaatoBidAdapter.js'; import * as utils from 'src/utils.js'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; // load modules that register ORTB processors import 'src/prebid.js' @@ -72,50 +72,50 @@ describe('smaatoBidAdapterTest', () => { }); it('is invalid, when params object is empty', () => { - expect(spec.isBidRequestValid({params: {}})).to.be.false; + expect(spec.isBidRequestValid({ params: {} })).to.be.false; }); it('is invalid, when publisherId is present but of wrong type', () => { - expect(spec.isBidRequestValid({params: {publisherId: 123}})).to.be.false; + expect(spec.isBidRequestValid({ params: { publisherId: 123 } })).to.be.false; }); describe('for ad pod / long form video requests', () => { - const ADPOD = {video: {context: 'adpod'}} + const ADPOD = { video: { context: 'adpod' } } it('is invalid, when adbreakId is missing', () => { - expect(spec.isBidRequestValid({mediaTypes: ADPOD, params: {publisherId: '123'}})).to.be.false; + expect(spec.isBidRequestValid({ mediaTypes: ADPOD, params: { publisherId: '123' } })).to.be.false; }); it('is invalid, when adbreakId is present but of wrong type', () => { - expect(spec.isBidRequestValid({mediaTypes: ADPOD, params: {publisherId: '123', adbreakId: 456}})).to.be.false; + expect(spec.isBidRequestValid({ mediaTypes: ADPOD, params: { publisherId: '123', adbreakId: 456 } })).to.be.false; }); it('is valid, when required params are present', () => { - expect(spec.isBidRequestValid({mediaTypes: ADPOD, params: {publisherId: '123', adbreakId: '456'}})).to.be.true; + expect(spec.isBidRequestValid({ mediaTypes: ADPOD, params: { publisherId: '123', adbreakId: '456' } })).to.be.true; }); it('is invalid, when forbidden adspaceId param is present', () => { expect(spec.isBidRequestValid({ mediaTypes: ADPOD, - params: {publisherId: '123', adbreakId: '456', adspaceId: '42'} + params: { publisherId: '123', adbreakId: '456', adspaceId: '42' } })).to.be.false; }); }); describe('for non adpod requests', () => { it('is invalid, when adspaceId is missing', () => { - expect(spec.isBidRequestValid({params: {publisherId: '123'}})).to.be.false; + expect(spec.isBidRequestValid({ params: { publisherId: '123' } })).to.be.false; }); it('is invalid, when adspaceId is present but of wrong type', () => { - expect(spec.isBidRequestValid({params: {publisherId: '123', adspaceId: 456}})).to.be.false; + expect(spec.isBidRequestValid({ params: { publisherId: '123', adspaceId: 456 } })).to.be.false; }); it('is valid, when required params are present for minimal request', () => { - expect(spec.isBidRequestValid({params: {publisherId: '123', adspaceId: '456'}})).to.be.true; + expect(spec.isBidRequestValid({ params: { publisherId: '123', adspaceId: '456' } })).to.be.true; }); it('is invalid, when forbidden adbreakId param is present', () => { - expect(spec.isBidRequestValid({params: {publisherId: '123', adspaceId: '456', adbreakId: '42'}})).to.be.false; + expect(spec.isBidRequestValid({ params: { publisherId: '123', adspaceId: '456', adbreakId: '42' } })).to.be.false; }); }); }); @@ -291,7 +291,7 @@ describe('smaatoBidAdapterTest', () => { }, }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.site.id).to.exist.and.to.be.a('string'); @@ -316,7 +316,7 @@ describe('smaatoBidAdapterTest', () => { }, }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.dooh.id).to.exist.and.to.be.a('string'); @@ -346,7 +346,7 @@ describe('smaatoBidAdapterTest', () => { }, }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.device.language).to.equal(language); @@ -372,7 +372,7 @@ describe('smaatoBidAdapterTest', () => { }, }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.regs.coppa).to.equal(1); @@ -401,7 +401,7 @@ describe('smaatoBidAdapterTest', () => { } }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.regs.ext.gpp).to.eql('gppString'); @@ -416,8 +416,8 @@ describe('smaatoBidAdapterTest', () => { }); it('sends instl if instl exists', () => { - const instl = {instl: 1}; - const bidRequestWithInstl = Object.assign({}, singleBannerBidRequest, {ortb2Imp: instl}); + const instl = { instl: 1 }; + const bidRequestWithInstl = Object.assign({}, singleBannerBidRequest, { ortb2Imp: instl }); const reqs = spec.buildRequests([bidRequestWithInstl], defaultBidderRequest); @@ -462,7 +462,7 @@ describe('smaatoBidAdapterTest', () => { } }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.user.gender).to.equal('M'); @@ -512,7 +512,7 @@ describe('smaatoBidAdapterTest', () => { } }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.regs.ext.dsa.dsarequired).to.eql(2); @@ -529,7 +529,7 @@ describe('smaatoBidAdapterTest', () => { } }; - const reqs = spec.buildRequests([singleBannerBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([singleBannerBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.regs.ext.dsa).to.be.undefined; @@ -566,7 +566,7 @@ describe('smaatoBidAdapterTest', () => { skip: 1, skipmin: 5, api: [7], - ext: {rewarded: 0} + ext: { rewarded: 0 } }; const VIDEO_OUTSTREAM_OPENRTB_IMP = { mimes: ['video/mp4', 'video/quicktime', 'video/3gpp', 'video/x-m4v'], @@ -633,8 +633,8 @@ describe('smaatoBidAdapterTest', () => { }); it('sends instl if instl exists', () => { - const instl = {instl: 1}; - const bidRequestWithInstl = Object.assign({}, singleVideoBidRequest, {ortb2Imp: instl}); + const instl = { instl: 1 }; + const bidRequestWithInstl = Object.assign({}, singleVideoBidRequest, { ortb2Imp: instl }); const reqs = spec.buildRequests([bidRequestWithInstl], defaultBidderRequest); @@ -724,8 +724,8 @@ describe('smaatoBidAdapterTest', () => { }); it('sends instl if instl exists', () => { - const instl = {instl: 1}; - const bidRequestWithInstl = Object.assign({}, longFormVideoBidRequest, {ortb2Imp: instl}); + const instl = { instl: 1 }; + const bidRequestWithInstl = Object.assign({}, longFormVideoBidRequest, { ortb2Imp: instl }); const reqs = spec.buildRequests([bidRequestWithInstl], defaultBidderRequest); @@ -754,7 +754,7 @@ describe('smaatoBidAdapterTest', () => { }); it('sends brand category exclusion as true when config is set to true', () => { - config.setConfig({adpod: {brandCategoryExclusion: true}}); + config.setConfig({ adpod: { brandCategoryExclusion: true } }); const reqs = spec.buildRequests([longFormVideoBidRequest], defaultBidderRequest); @@ -763,7 +763,7 @@ describe('smaatoBidAdapterTest', () => { }); it('sends brand category exclusion as false when config is set to false', () => { - config.setConfig({adpod: {brandCategoryExclusion: false}}); + config.setConfig({ adpod: { brandCategoryExclusion: false } }); const reqs = spec.buildRequests([longFormVideoBidRequest], defaultBidderRequest); @@ -1159,7 +1159,7 @@ describe('smaatoBidAdapterTest', () => { it('when geo and ifa info present, then add both to device object', () => { const inAppBidRequest = utils.deepClone(inAppBidRequestWithoutAppParams); - inAppBidRequest.params.app = {ifa: DEVICE_ID, geo: LOCATION}; + inAppBidRequest.params.app = { ifa: DEVICE_ID, geo: LOCATION }; const reqs = spec.buildRequests([inAppBidRequest], defaultBidderRequest); @@ -1180,9 +1180,9 @@ describe('smaatoBidAdapterTest', () => { }; const inAppBidRequest = utils.deepClone(inAppBidRequestWithoutAppParams); - inAppBidRequest.params.app = {ifa: DEVICE_ID, geo: LOCATION}; + inAppBidRequest.params.app = { ifa: DEVICE_ID, geo: LOCATION }; - const reqs = spec.buildRequests([inAppBidRequest], {...defaultBidderRequest, ortb2}); + const reqs = spec.buildRequests([inAppBidRequest], { ...defaultBidderRequest, ortb2 }); const req = extractPayloadOfFirstAndOnlyRequest(reqs); expect(req.device.geo.lat).to.equal(53.5488); @@ -1192,7 +1192,7 @@ describe('smaatoBidAdapterTest', () => { it('when ifa is present but geo is missing, then add only ifa to device object', () => { const inAppBidRequest = utils.deepClone(inAppBidRequestWithoutAppParams); - inAppBidRequest.params.app = {ifa: DEVICE_ID}; + inAppBidRequest.params.app = { ifa: DEVICE_ID }; const reqs = spec.buildRequests([inAppBidRequest], defaultBidderRequest); @@ -1203,7 +1203,7 @@ describe('smaatoBidAdapterTest', () => { it('when geo is present but ifa is missing, then add only geo to device object', () => { const inAppBidRequest = utils.deepClone(inAppBidRequestWithoutAppParams); - inAppBidRequest.params.app = {geo: LOCATION}; + inAppBidRequest.params.app = { geo: LOCATION }; const reqs = spec.buildRequests([inAppBidRequest], defaultBidderRequest); @@ -1246,7 +1246,7 @@ describe('smaatoBidAdapterTest', () => { tdid: '89145' }, userIdAsEids: [ - {id: 1}, {id: 2} + { id: 1 }, { id: 2 } ] }; @@ -1290,7 +1290,7 @@ describe('smaatoBidAdapterTest', () => { }); describe('interpretResponse', () => { - function buildBidRequest(payloadAsJsObj = {imp: [{}]}) { + function buildBidRequest(payloadAsJsObj = { imp: [{}] }) { return { method: 'POST', url: 'https://prebid.ad.smaato.net/oapi/prebid', @@ -1385,7 +1385,7 @@ describe('smaatoBidAdapterTest', () => { adm = ''; break; case ADTYPE_NATIVE: - adm = JSON.stringify({native: NATIVE_RESPONSE}) + adm = JSON.stringify({ native: NATIVE_RESPONSE }) break; default: throw Error('Invalid AdType'); @@ -1436,7 +1436,7 @@ describe('smaatoBidAdapterTest', () => { }; it('returns empty array on no bid responses', () => { - const response_with_empty_body = {body: {}}; + const response_with_empty_body = { body: {} }; const bids = spec.interpretResponse(response_with_empty_body, buildBidRequest()); @@ -1539,7 +1539,7 @@ describe('smaatoBidAdapterTest', () => { }); describe('ad pod', () => { - const bidRequestWithAdpodContext = buildBidRequest({imp: [{video: {ext: {context: 'adpod'}}}]}); + const bidRequestWithAdpodContext = buildBidRequest({ imp: [{ video: { ext: { context: 'adpod' } } }] }); const PRIMARY_CAT_ID = 1337 const serverResponse = { body: { @@ -1576,7 +1576,7 @@ describe('smaatoBidAdapterTest', () => { } ] }, - headers: {get: () => undefined} + headers: { get: () => undefined } }; it('sets required values for adpod bid from server response', () => { @@ -1610,7 +1610,7 @@ describe('smaatoBidAdapterTest', () => { }); it('sets primary category id in case of enabled brand category exclusion', () => { - config.setConfig({adpod: {brandCategoryExclusion: true}}); + config.setConfig({ adpod: { brandCategoryExclusion: true } }); const bids = spec.interpretResponse(serverResponse, bidRequestWithAdpodContext) @@ -1640,7 +1640,7 @@ describe('smaatoBidAdapterTest', () => { it('uses net revenue flag send from server', () => { const resp = buildOpenRtbBidResponse(ADTYPE_IMG); - resp.body.seatbid[0].bid[0].ext = {net: false}; + resp.body.seatbid[0].bid[0].ext = { net: false }; const bids = spec.interpretResponse(resp, buildBidRequest()); @@ -1687,7 +1687,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when pixelEnabled true then returns image sync', () => { - expect(spec.getUserSyncs({pixelEnabled: true}, null, null, null)).to.deep.equal( + expect(spec.getUserSyncs({ pixelEnabled: true }, null, null, null)).to.deep.equal( [ { type: 'image', @@ -1698,7 +1698,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when iframeEnabled true then returns iframe sync', () => { - expect(spec.getUserSyncs({iframeEnabled: true}, null, null, null)).to.deep.equal( + expect(spec.getUserSyncs({ iframeEnabled: true }, null, null, null)).to.deep.equal( [ { type: 'iframe', @@ -1709,8 +1709,8 @@ describe('smaatoBidAdapterTest', () => { }) it('when iframeEnabled true and syncsPerBidder then returns iframe sync', () => { - config.setConfig({userSync: {syncsPerBidder: 5}}); - expect(spec.getUserSyncs({iframeEnabled: true}, null, null, null)).to.deep.equal( + config.setConfig({ userSync: { syncsPerBidder: 5 } }); + expect(spec.getUserSyncs({ iframeEnabled: true }, null, null, null)).to.deep.equal( [ { type: 'iframe', @@ -1721,7 +1721,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when iframeEnabled and pixelEnabled true then returns iframe sync', () => { - expect(spec.getUserSyncs({pixelEnabled: true, iframeEnabled: true}, null, null, null)).to.deep.equal( + expect(spec.getUserSyncs({ pixelEnabled: true, iframeEnabled: true }, null, null, null)).to.deep.equal( [ { type: 'iframe', @@ -1732,7 +1732,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when pixelEnabled true and gdprConsent then returns image sync with gdpr params', () => { - expect(spec.getUserSyncs({pixelEnabled: true}, null, {gdprApplies: true, consentString: CONSENT_STRING}, null)).to.deep.equal( + expect(spec.getUserSyncs({ pixelEnabled: true }, null, { gdprApplies: true, consentString: CONSENT_STRING }, null)).to.deep.equal( [ { type: 'image', @@ -1743,7 +1743,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when iframeEnabled true and gdprConsent then returns iframe with gdpr params', () => { - expect(spec.getUserSyncs({iframeEnabled: true}, null, {gdprApplies: true, consentString: CONSENT_STRING}, null)).to.deep.equal( + expect(spec.getUserSyncs({ iframeEnabled: true }, null, { gdprApplies: true, consentString: CONSENT_STRING }, null)).to.deep.equal( [ { type: 'iframe', @@ -1754,7 +1754,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when pixelEnabled true and gdprConsent without gdpr then returns pixel sync with gdpr_consent', () => { - expect(spec.getUserSyncs({pixelEnabled: true}, null, {consentString: CONSENT_STRING}, null), null).to.deep.equal( + expect(spec.getUserSyncs({ pixelEnabled: true }, null, { consentString: CONSENT_STRING }, null), null).to.deep.equal( [ { type: 'image', @@ -1765,7 +1765,7 @@ describe('smaatoBidAdapterTest', () => { }) it('when iframeEnabled true and gdprConsent without gdpr then returns iframe sync with gdpr_consent', () => { - expect(spec.getUserSyncs({iframeEnabled: true}, null, {consentString: CONSENT_STRING}, null), null).to.deep.equal( + expect(spec.getUserSyncs({ iframeEnabled: true }, null, { consentString: CONSENT_STRING }, null), null).to.deep.equal( [ { type: 'iframe', diff --git a/test/spec/modules/smarthubBidAdapter_spec.js b/test/spec/modules/smarthubBidAdapter_spec.js index 29607365c68..b2bf9a3bdd2 100644 --- a/test/spec/modules/smarthubBidAdapter_spec.js +++ b/test/spec/modules/smarthubBidAdapter_spec.js @@ -446,7 +446,7 @@ describe('SmartHubBidAdapter', function () { const syncData = spec.getUserSyncs({}, {}, { consentString: 'ALL', gdprApplies: true, - }, {}); + }, undefined); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -455,9 +455,7 @@ describe('SmartHubBidAdapter', function () { expect(syncData[0].url).to.equal('https://us4.shb-sync.com/image?pbjs=1&gdpr=1&gdpr_consent=ALL&coppa=0&pid=360') }); it('Should return array of objects with CCPA values', function() { - const syncData = spec.getUserSyncs({}, {}, {}, { - consentString: '1---' - }); + const syncData = spec.getUserSyncs({}, {}, {}, '1---'); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') @@ -466,7 +464,7 @@ describe('SmartHubBidAdapter', function () { expect(syncData[0].url).to.equal('https://us4.shb-sync.com/image?pbjs=1&ccpa_consent=1---&coppa=0&pid=360') }); it('Should return array of objects with GPP values', function() { - const syncData = spec.getUserSyncs({}, {}, {}, {}, { + const syncData = spec.getUserSyncs({}, {}, {}, undefined, { gppString: 'ab12345', applicableSections: [8] }); @@ -478,7 +476,7 @@ describe('SmartHubBidAdapter', function () { expect(syncData[0].url).to.equal('https://us4.shb-sync.com/image?pbjs=1&gpp=ab12345&gpp_sid=8&coppa=0&pid=360') }); it('Should return iframe type if iframeEnabled is true', function() { - const syncData = spec.getUserSyncs({iframeEnabled: true}, {}, {}, {}, {}); + const syncData = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, undefined, {}); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object') expect(syncData[0].type).to.be.a('string') diff --git a/test/spec/modules/smarticoBidAdapter_spec.js b/test/spec/modules/smarticoBidAdapter_spec.js index 50fba36e23f..7f0a2df62ae 100644 --- a/test/spec/modules/smarticoBidAdapter_spec.js +++ b/test/spec/modules/smarticoBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec} from 'modules/smarticoBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec } from 'modules/smarticoBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; describe('smarticoBidAdapter', function () { const adapter = newBidder(spec); @@ -13,7 +13,7 @@ describe('smarticoBidAdapter', function () { bidderRequestsCount: 1, bidderWinsCount: 0, bidId: '22499d052045', - mediaTypes: {banner: {sizes: [[300, 250]]}}, + mediaTypes: { banner: { sizes: [[300, 250]] } }, params: { token: 'FNVzUGZn9ebpIOoheh3kEJ2GQ6H6IyMH39sHXaya', placementId: 'testPlacementId' @@ -41,7 +41,7 @@ describe('smarticoBidAdapter', function () { }); }); describe('buildRequests', function () { - const bidRequests = [ bid ]; + const bidRequests = [bid]; const request = spec.buildRequests(bidRequests, bidderRequests); it('sends bid request via POST', function () { expect(request.method).to.equal('POST'); @@ -99,7 +99,8 @@ describe('smarticoBidAdapter', function () { meta: { advertiserDomains: ['www.advertiser.com'], advertiserName: 'Advertiser' - }}]; + } + }]; const result = spec.interpretResponse(serverResponse, bidRequest); it('should contain correct creativeId', function () { expect(result[0].creativeId).to.equal(expectedResponse[0].creativeId) diff --git a/test/spec/modules/smartyadsBidAdapter_spec.js b/test/spec/modules/smartyadsBidAdapter_spec.js index 2a3f1e8443c..67e24e0696d 100644 --- a/test/spec/modules/smartyadsBidAdapter_spec.js +++ b/test/spec/modules/smartyadsBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from '../../../modules/smartyadsBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from '../../../modules/smartyadsBidAdapter.js'; import { config } from '../../../src/config.js'; -import {server} from '../../mocks/xhr.js'; +import { server } from '../../mocks/xhr.js'; describe('SmartyadsAdapter', function () { const bid = { @@ -111,7 +111,7 @@ describe('SmartyadsAdapter', function () { netRevenue: true, currency: 'USD', dealId: '1', - meta: {advertiserDomains: ['example.com']} + meta: { advertiserDomains: ['example.com'] } }] }; const bannerResponses = spec.interpretResponse(banner); diff --git a/test/spec/modules/smartytechBidAdapter_spec.js b/test/spec/modules/smartytechBidAdapter_spec.js index 17e1bb59bed..7340d65efc1 100644 --- a/test/spec/modules/smartytechBidAdapter_spec.js +++ b/test/spec/modules/smartytechBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai'; -import {spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH, getAliasUserId, storage} from 'modules/smartytechBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { expect } from 'chai'; +import { spec, ENDPOINT_PROTOCOL, ENDPOINT_DOMAIN, ENDPOINT_PATH, getAliasUserId, storage } from 'modules/smartytechBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; import sinon from 'sinon'; @@ -135,13 +135,13 @@ describe('SmartyTechDSPAdapter: isBidRequestValid', function () { }); function mockRandomSizeArray(len) { - return Array.apply(null, {length: len}).map(i => { + return Array.apply(null, { length: len }).map(i => { return [Math.floor(Math.random() * 800), Math.floor(Math.random() * 800)] }); } function mockBidRequestListData(mediaType, size, customSizes) { - return Array.apply(null, {length: size}).map((i, index) => { + return Array.apply(null, { length: size }).map((i, index) => { const id = Math.floor(Math.random() * 800) * (index + 1); let mediaTypes; const params = { @@ -436,7 +436,7 @@ describe('SmartyTechDSPAdapter: buildRequests with user IDs', () => { it('should not include userIds when userIdAsEids is undefined', () => { const bidRequestWithUndefinedUserIds = mockBidRequestListData('banner', 2, []).map(req => { - const {userIdAsEids, ...requestWithoutUserIds} = req; + const { userIdAsEids, ...requestWithoutUserIds } = req; return requestWithoutUserIds; }); const request = spec.buildRequests(bidRequestWithUndefinedUserIds, mockReferer); diff --git a/test/spec/modules/smilewantedBidAdapter_spec.js b/test/spec/modules/smilewantedBidAdapter_spec.js index e1d740ea19e..3d8f55c17a7 100644 --- a/test/spec/modules/smilewantedBidAdapter_spec.js +++ b/test/spec/modules/smilewantedBidAdapter_spec.js @@ -635,14 +635,14 @@ describe('smilewantedBidAdapterTests', function () { }); it('SmileWanted - Verify user sync - empty data', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}, {}, {}, null); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, {}, null); expect(syncs).to.have.lengthOf(1); expect(syncs[0].type).to.equal('iframe'); expect(syncs[0].url).to.equal('https://csync.smilewanted.com'); }); it('SmileWanted - Verify user sync', function () { - let syncs = spec.getUserSyncs({iframeEnabled: true}, {}, { + let syncs = spec.getUserSyncs({ iframeEnabled: true }, {}, { consentString: 'foo' }, '1NYN'); expect(syncs).to.have.lengthOf(1); diff --git a/test/spec/modules/smootBidAdapter_spec.js b/test/spec/modules/smootBidAdapter_spec.js index d9c5580e60d..7ab8100bbe1 100644 --- a/test/spec/modules/smootBidAdapter_spec.js +++ b/test/spec/modules/smootBidAdapter_spec.js @@ -544,7 +544,7 @@ describe('SmootBidAdapter', function () { consentString: 'ALL', gdprApplies: true, }, - {} + undefined ); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object'); @@ -560,9 +560,7 @@ describe('SmootBidAdapter', function () { {}, {}, {}, - { - consentString: '1---', - } + '1---' ); expect(syncData).to.be.an('array').which.is.not.empty; expect(syncData[0]).to.be.an('object'); @@ -578,7 +576,7 @@ describe('SmootBidAdapter', function () { {}, {}, {}, - {}, + undefined, { gppString: 'abc123', applicableSections: [8], diff --git a/test/spec/modules/snigelBidAdapter_spec.js b/test/spec/modules/snigelBidAdapter_spec.js index faeba529abe..d8572ce2dcf 100644 --- a/test/spec/modules/snigelBidAdapter_spec.js +++ b/test/spec/modules/snigelBidAdapter_spec.js @@ -1,9 +1,9 @@ -import {expect} from 'chai'; -import {spec} from 'modules/snigelBidAdapter.js'; -import {config} from 'src/config.js'; -import {isValid} from 'src/adapters/bidderFactory.js'; -import {registerActivityControl} from 'src/activities/rules.js'; -import {ACTIVITY_ACCESS_DEVICE} from 'src/activities/activities.js'; +import { expect } from 'chai'; +import { spec } from 'modules/snigelBidAdapter.js'; +import { config } from 'src/config.js'; +import { isValid } from 'src/adapters/bidderFactory.js'; +import { registerActivityControl } from 'src/activities/rules.js'; +import { ACTIVITY_ACCESS_DEVICE } from 'src/activities/activities.js'; const BASE_BID_REQUEST = { adUnitCode: 'top_leaderboard', @@ -18,7 +18,7 @@ const BASE_BID_REQUEST = { transactionId: 'trans_test', }; const makeBidRequest = function (overrides) { - return {...BASE_BID_REQUEST, ...overrides}; + return { ...BASE_BID_REQUEST, ...overrides }; }; const BASE_BIDDER_REQUEST = { @@ -30,7 +30,7 @@ const BASE_BIDDER_REQUEST = { }, }; const makeBidderRequest = function (overrides) { - return {...BASE_BIDDER_REQUEST, ...overrides}; + return { ...BASE_BIDDER_REQUEST, ...overrides }; }; const DUMMY_USP_CONSENT = '1YYN'; @@ -45,7 +45,7 @@ describe('snigelBidAdapter', function () { }); it('should return true if placement provided', function () { - const bidRequest = makeBidRequest({params: {placement: 'top_leaderboard'}}); + const bidRequest = makeBidRequest({ params: { placement: 'top_leaderboard' } }); expect(spec.isBidRequestValid(bidRequest)).to.equal(true); }); }); @@ -58,8 +58,8 @@ describe('snigelBidAdapter', function () { it('should build a single request for every impression and its placement', function () { const bidderRequest = Object.assign({}, BASE_BIDDER_REQUEST); const bidRequests = [ - makeBidRequest({bidId: 'a', adUnitCode: 'au_a', params: {placement: 'top_leaderboard'}}), - makeBidRequest({bidId: 'b', adUnitCode: 'au_b', params: {placement: 'bottom_leaderboard'}}), + makeBidRequest({ bidId: 'a', adUnitCode: 'au_a', params: { placement: 'top_leaderboard' } }), + makeBidRequest({ bidId: 'b', adUnitCode: 'au_b', params: { placement: 'bottom_leaderboard' } }), ]; const request = spec.buildRequests(bidRequests, bidderRequest); @@ -135,9 +135,9 @@ describe('snigelBidAdapter', function () { it('should forward refresh information', function () { const bidderRequest = Object.assign({}, BASE_BIDDER_REQUEST); - const topLeaderboard = makeBidRequest({adUnitCode: 'top_leaderboard'}); - const bottomLeaderboard = makeBidRequest({adUnitCode: 'bottom_leaderboard'}); - const sidebar = makeBidRequest({adUnitCode: 'sidebar'}); + const topLeaderboard = makeBidRequest({ adUnitCode: 'top_leaderboard' }); + const bottomLeaderboard = makeBidRequest({ adUnitCode: 'bottom_leaderboard' }); + const sidebar = makeBidRequest({ adUnitCode: 'sidebar' }); // first auction, no refresh let request = spec.buildRequests([topLeaderboard, bottomLeaderboard], bidderRequest); @@ -199,9 +199,9 @@ describe('snigelBidAdapter', function () { it('should increment placement counter for each placement', function () { const bidderRequest = Object.assign({}, BASE_BIDDER_REQUEST); - const topLeaderboard = makeBidRequest({adUnitCode: 'top_leaderboard', params: {placement: 'ros'}}); - const bottomLeaderboard = makeBidRequest({adUnitCode: 'bottom_leaderboard', params: {placement: 'ros'}}); - const sidebar = makeBidRequest({adUnitCode: 'sidebar', params: {placement: 'other'}}); + const topLeaderboard = makeBidRequest({ adUnitCode: 'top_leaderboard', params: { placement: 'ros' } }); + const bottomLeaderboard = makeBidRequest({ adUnitCode: 'bottom_leaderboard', params: { placement: 'ros' } }); + const sidebar = makeBidRequest({ adUnitCode: 'sidebar', params: { placement: 'other' } }); let request = spec.buildRequests([topLeaderboard, bottomLeaderboard, sidebar], bidderRequest); expect(request).to.have.property('data'); @@ -231,11 +231,11 @@ describe('snigelBidAdapter', function () { describe('interpretResponse', function () { it('should not return any bids if the request failed', function () { expect(spec.interpretResponse({}, {})).to.be.empty; - expect(spec.interpretResponse({body: 'Some error message'}, {})).to.be.empty; + expect(spec.interpretResponse({ body: 'Some error message' }, {})).to.be.empty; }); it('should not return any bids if the request did not return any bids either', function () { - expect(spec.interpretResponse({body: {bids: []}})).to.be.empty; + expect(spec.interpretResponse({ body: { bids: [] } })).to.be.empty; }); it('should return valid bids with additional meta information', function () { @@ -259,7 +259,7 @@ describe('snigelBidAdapter', function () { }, }; - const bids = spec.interpretResponse(serverResponse, {bidderRequest: {bids: [BASE_BID_REQUEST]}}); + const bids = spec.interpretResponse(serverResponse, { bidderRequest: { bids: [BASE_BID_REQUEST] } }); expect(bids.length).to.equal(1); const bid = bids[0]; expect(isValid(BASE_BID_REQUEST.adUnitCode, bid)).to.be.true; @@ -353,7 +353,7 @@ describe('snigelBidAdapter', function () { consentString: DUMMY_GDPR_CONSENT_STRING, vendorData: { purpose: { - consents: {1: true}, + consents: { 1: true }, }, }, }; @@ -400,7 +400,7 @@ describe('snigelBidAdapter', function () { it('should omit session ID if no device access', function () { const bidderRequest = makeBidderRequest(); const unregisterRule = registerActivityControl(ACTIVITY_ACCESS_DEVICE, 'denyAccess', () => { - return {allow: false, reason: 'no consent'}; + return { allow: false, reason: 'no consent' }; }); try { @@ -419,10 +419,10 @@ describe('snigelBidAdapter', function () { gdprApplies: true, vendorData: { purpose: { - consents: {1: true, 2: true, 3: true, 4: true, 5: true}, + consents: { 1: true, 2: true, 3: true, 4: true, 5: true }, }, vendor: { - consents: {[spec.gvlid]: true}, + consents: { [spec.gvlid]: true }, }, }, }, @@ -432,7 +432,7 @@ describe('snigelBidAdapter', function () { let data = JSON.parse(request.data); expect(data.gdprConsent).to.be.true; - let bidderRequest = {...baseBidderRequest, ...{gdprConsent: {vendorData: {purpose: {consents: {1: false}}}}}}; + let bidderRequest = { ...baseBidderRequest, ...{ gdprConsent: { vendorData: { purpose: { consents: { 1: false } } } } } }; request = spec.buildRequests([], bidderRequest); expect(request).to.have.property('data'); data = JSON.parse(request.data); @@ -440,7 +440,7 @@ describe('snigelBidAdapter', function () { bidderRequest = { ...baseBidderRequest, - ...{gdprConsent: {vendorData: {vendor: {consents: {[spec.gvlid]: false}}}}}, + ...{ gdprConsent: { vendorData: { vendor: { consents: { [spec.gvlid]: false } } } } }, }; request = spec.buildRequests([], bidderRequest); expect(request).to.have.property('data'); diff --git a/test/spec/modules/sonaradsBidAdapter_spec.js b/test/spec/modules/sonaradsBidAdapter_spec.js index e0afd0c7d23..140fa8c95d0 100644 --- a/test/spec/modules/sonaradsBidAdapter_spec.js +++ b/test/spec/modules/sonaradsBidAdapter_spec.js @@ -171,7 +171,7 @@ describe('bridgeuppBidAdapter_spec', function () { } } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.site.domain).to.equal(SITE_DOMAIN_NAME); expect(ortbRequest.site.publisher.domain).to.equal('sonarads.com'); expect(ortbRequest.site.page).to.equal(SITE_PAGE); @@ -220,7 +220,7 @@ describe('bridgeuppBidAdapter_spec', function () { } } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.device.dnt).to.equal(1); expect(ortbRequest.device.lmt).to.equal(0); expect(ortbRequest.device.js).to.equal(0); @@ -238,7 +238,7 @@ describe('bridgeuppBidAdapter_spec', function () { }); it('should properly build a request with source object', async function () { - const expectedSchain = {id: 'prebid'}; + const expectedSchain = { id: 'prebid' }; const ortb2 = { source: { pchain: 'sonarads', @@ -262,7 +262,7 @@ describe('bridgeuppBidAdapter_spec', function () { }, }, ]; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.source.ext.schain).to.deep.equal(expectedSchain); expect(ortbRequest.source.pchain).to.equal('sonarads'); }); @@ -351,7 +351,7 @@ describe('bridgeuppBidAdapter_spec', function () { } }; - const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({...bidderRequest, ortb2})).data; + const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest({ ...bidderRequest, ortb2 })).data; expect(ortbRequest.regs.coppa).to.equal(1); expect(ortbRequest.regs.gpp).to.equal('consent_string'); expect(ortbRequest.regs.gpp_sid).to.deep.equal([0, 1, 2]); @@ -565,7 +565,7 @@ describe('bridgeuppBidAdapter_spec', function () { it('should properly build a request when coppa is true', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const ortbRequest = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)).data; expect(ortbRequest.regs.coppa).to.equal(1); @@ -574,7 +574,7 @@ describe('bridgeuppBidAdapter_spec', function () { it('should properly build a request when coppa is false', async function () { const bidRequests = []; const bidderRequest = {}; - config.setConfig({coppa: false}); + config.setConfig({ coppa: false }); const buildRequests = spec.buildRequests(bidRequests, await addFPDToBidderRequest(bidderRequest)); const ortbRequest = buildRequests.data; expect(ortbRequest.regs.coppa).to.equal(0); @@ -623,7 +623,7 @@ describe('bridgeuppBidAdapter_spec', function () { siteId: 'site-id-12' }, getFloor: () => { - return {currency: 'USD', floor: 1.23, size: '*', mediaType: '*'}; + return { currency: 'USD', floor: 1.23, size: '*', mediaType: '*' }; } } ]; @@ -721,7 +721,7 @@ describe('bridgeuppBidAdapter_spec', function () { return undefined } }, - body: {seatbid: []} + body: { seatbid: [] } }; const interpretedBids = spec.interpretResponse(serverResponse, request); diff --git a/test/spec/modules/sonobiBidAdapter_spec.js b/test/spec/modules/sonobiBidAdapter_spec.js index f7b1d858d50..e9e098b4f44 100644 --- a/test/spec/modules/sonobiBidAdapter_spec.js +++ b/test/spec/modules/sonobiBidAdapter_spec.js @@ -5,7 +5,7 @@ import { userSync } from '../../../src/userSync.js'; import { config } from 'src/config.js'; import * as gptUtils from '../../../libraries/gptUtils/gptUtils.js'; import { parseQS } from '../../../src/utils.js' -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; describe('SonobiBidAdapter', function () { const adapter = newBidder(spec) const originalBuildRequests = spec.buildRequests; diff --git a/test/spec/modules/sovrnBidAdapter_spec.js b/test/spec/modules/sovrnBidAdapter_spec.js index c442b1d53db..41a264f45e7 100644 --- a/test/spec/modules/sovrnBidAdapter_spec.js +++ b/test/spec/modules/sovrnBidAdapter_spec.js @@ -1,6 +1,6 @@ -import {expect} from 'chai' -import {spec} from 'modules/sovrnBidAdapter.js' -import {config} from 'src/config.js' +import { expect } from 'chai' +import { spec } from 'modules/sovrnBidAdapter.js' +import { config } from 'src/config.js' import * as utils from 'src/utils.js' const ENDPOINT = `https://ap.lijit.com/rtb/bid?src=$$REPO_AND_VERSION$$` @@ -113,7 +113,7 @@ describe('sovrnBidAdapter', function() { const payload = JSON.parse(request.data) const impression = payload.imp[0] - expect(impression.banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]) + expect(impression.banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]) expect(impression.banner.w).to.equal(1) expect(impression.banner.h).to.equal(1) }) @@ -265,7 +265,7 @@ describe('sovrnBidAdapter', function() { const payload = JSON.parse(request.data) const impression = payload.imp[0] - expect(impression.banner.format).to.deep.equal([{w: 300, h: 250}]) + expect(impression.banner.format).to.deep.equal([{ w: 300, h: 250 }]) expect(impression.banner.w).to.equal(1) expect(impression.banner.h).to.equal(1) }) @@ -331,7 +331,7 @@ describe('sovrnBidAdapter', function() { gdprApplies: true }, } - const {regs} = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) + const { regs } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) expect(regs.coppa).to.be.undefined }) @@ -349,7 +349,7 @@ describe('sovrnBidAdapter', function() { timeout: 3000, bids: [baseBidRequest] } - const {regs} = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) + const { regs } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) expect(regs.coppa).to.equal(1) }) @@ -366,7 +366,7 @@ describe('sovrnBidAdapter', function() { gdprApplies: true }, } - const {bcat} = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) + const { bcat } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) expect(bcat).to.be.undefined }) @@ -382,7 +382,7 @@ describe('sovrnBidAdapter', function() { timeout: 3000, bids: [baseBidRequest] } - const {bcat} = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) + const { bcat } = JSON.parse(spec.buildRequests([baseBidRequest], bidderRequest).data) expect(bcat).to.exist.and.to.be.a('array') expect(bcat).to.deep.equal(['IAB1-1', 'IAB1-2']) }) @@ -570,7 +570,7 @@ describe('sovrnBidAdapter', function() { it('should use the floor provided from the floor module if present', function() { const floorBid = { ...baseBidRequest, - getFloor: () => ({currency: 'USD', floor: 1.10}), + getFloor: () => ({ currency: 'USD', floor: 1.10 }), params: { tagid: 1234, bidfloor: 2.00 @@ -610,7 +610,7 @@ describe('sovrnBidAdapter', function() { it('floor should be undefined if there is incorrect floor value from the floor module', function() { const floorBid = { ...baseBidRequest, - getFloor: () => ({currency: 'USD', floor: 'incorrect_value'}), + getFloor: () => ({ currency: 'USD', floor: 'incorrect_value' }), params: { tagid: 1234 } @@ -645,7 +645,7 @@ describe('sovrnBidAdapter', function() { } }; - const request = spec.buildRequests([baseBidRequest], {...baseBidderRequest, ortb2}) + const request = spec.buildRequests([baseBidRequest], { ...baseBidderRequest, ortb2 }) const { user, site } = JSON.parse(request.data) expect(user.data).to.equal('some user data') @@ -1199,7 +1199,7 @@ describe('sovrnBidAdapter', function() { const payload = JSON.parse(request.data) it('gets sizes from mediaTypes.banner', function() { - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]) + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]) expect(payload.imp[0].banner.w).to.equal(1) expect(payload.imp[0].banner.h).to.equal(1) }) diff --git a/test/spec/modules/ssmasBidAdapter_spec.js b/test/spec/modules/ssmasBidAdapter_spec.js index a97a40caeac..70ca4c4b478 100644 --- a/test/spec/modules/ssmasBidAdapter_spec.js +++ b/test/spec/modules/ssmasBidAdapter_spec.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { spec, SSMAS_CODE, SSMAS_ENDPOINT, SSMAS_REQUEST_METHOD } from 'modules/ssmasBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; import * as utils from 'src/utils.js'; describe('ssmasBidAdapter', function () { @@ -68,7 +68,7 @@ describe('ssmasBidAdapter', function () { it('test bad bid request', function () { // empty bid - expect(spec.isBidRequestValid({bidId: '', params: {}})).to.be.false; + expect(spec.isBidRequestValid({ bidId: '', params: {} })).to.be.false; // empty bidId bid.bidId = ''; diff --git a/test/spec/modules/ssp_genieeBidAdapter_spec.js b/test/spec/modules/ssp_genieeBidAdapter_spec.js index ab7e99ab5e5..a207b21aa73 100644 --- a/test/spec/modules/ssp_genieeBidAdapter_spec.js +++ b/test/spec/modules/ssp_genieeBidAdapter_spec.js @@ -364,20 +364,20 @@ describe('ssp_genieeBidAdapter', function () { it('should include only imuid in extuid query when only imuid exists', function () { const imuid = 'b.a4ad1d3eeb51e600'; - const request = spec.buildRequests([{...BANNER_BID, userId: {imuid}}]); + const request = spec.buildRequests([{ ...BANNER_BID, userId: { imuid } }]); expect(request[0].data.extuid).to.deep.equal(`im:${imuid}`); }); it('should include only id5id in extuid query when only id5id exists', function () { const id5id = 'id5id'; - const request = spec.buildRequests([{...BANNER_BID, userId: {id5id: {uid: id5id}}}]); + const request = spec.buildRequests([{ ...BANNER_BID, userId: { id5id: { uid: id5id } } }]); expect(request[0].data.extuid).to.deep.equal(`id5:${id5id}`); }); it('should include id5id and imuid in extuid query when id5id and imuid exists', function () { const imuid = 'b.a4ad1d3eeb51e600'; const id5id = 'id5id'; - const request = spec.buildRequests([{...BANNER_BID, userId: {id5id: {uid: id5id}, imuid: imuid}}]); + const request = spec.buildRequests([{ ...BANNER_BID, userId: { id5id: { uid: id5id }, imuid: imuid } }]); expect(request[0].data.extuid).to.deep.equal(`id5:${id5id}\tim:${imuid}`); }); diff --git a/test/spec/modules/stackadaptBidAdapter_spec.js b/test/spec/modules/stackadaptBidAdapter_spec.js index 00c799b52cc..1c761590011 100644 --- a/test/spec/modules/stackadaptBidAdapter_spec.js +++ b/test/spec/modules/stackadaptBidAdapter_spec.js @@ -242,7 +242,7 @@ describe('stackadaptBidAdapter', function () { bids: [bidderRequest] }) - const result = spec.interpretResponse(ortbResponse, {data: ortbRequest.data}); + const result = spec.interpretResponse(ortbResponse, { data: ortbRequest.data }); expect(result.length).to.equal(1); expect(result[0]).to.deep.equal(expectedBid); }); @@ -398,7 +398,7 @@ describe('stackadaptBidAdapter', function () { const ortbRequest = spec.buildRequests([bidderRequest1, bidderRequest2], { bids: [bidderRequest1, bidderRequest2] }) - const result = spec.interpretResponse(ortbResponse, {data: ortbRequest.data}); + const result = spec.interpretResponse(ortbResponse, { data: ortbRequest.data }); expect(result.length).to.equal(2); expect(result).to.deep.equal(expectedBids); }); @@ -472,7 +472,7 @@ describe('stackadaptBidAdapter', function () { bids: [bidderRequest] }) - const result = spec.interpretResponse(ortbResponse, {data: ortbRequest.data}); + const result = spec.interpretResponse(ortbResponse, { data: ortbRequest.data }); expect(result.length).to.equal(1); expect(result[0]).to.deep.equal(expectedBid); }); @@ -794,8 +794,8 @@ describe('stackadaptBidAdapter', function () { } } - const ortbRequest = spec.buildRequests(bidRequests, {...bidderRequestWithoutRefererDomain, ortb2}).data; - expect(ortbRequest.site.publisher).to.deep.equal({domain: 'https://publisher.com', id: '11111'}); + const ortbRequest = spec.buildRequests(bidRequests, { ...bidderRequestWithoutRefererDomain, ortb2 }).data; + expect(ortbRequest.site.publisher).to.deep.equal({ domain: 'https://publisher.com', id: '11111' }); }); it('should set first party side data publisher domain taking precedence over referer domain', function () { @@ -804,7 +804,7 @@ describe('stackadaptBidAdapter', function () { domain: 'https://publisher.com', } }; - const ortbRequest = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}).data; + const ortbRequest = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }).data; expect(ortbRequest.site.domain).to.equal('https://publisher.com'); }); @@ -812,7 +812,7 @@ describe('stackadaptBidAdapter', function () { const ortb2 = { bcat: ['IAB1', 'IAB2'] }; - const ortbRequest = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}).data; + const ortbRequest = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }).data; expect(ortbRequest.bcat).to.deep.equal(['IAB1', 'IAB2']); }); @@ -820,7 +820,7 @@ describe('stackadaptBidAdapter', function () { const ortb2 = { badv: ['chargers.com', 'house.com'] }; - const ortbRequest = spec.buildRequests(bidRequests, {...bidderRequest, ortb2}).data; + const ortbRequest = spec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }).data; expect(ortbRequest.badv).to.deep.equal(['chargers.com', 'house.com']); }); @@ -853,7 +853,7 @@ describe('stackadaptBidAdapter', function () { } } }; - const clonedBidderRequest = {...deepClone(bidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(bidderRequest), ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, clonedBidderRequest).data; expect(ortbRequest.user.ext.consent).to.equal(consentString); expect(ortbRequest.regs.ext.gdpr).to.equal(1); @@ -868,7 +868,7 @@ describe('stackadaptBidAdapter', function () { } } }; - const clonedBidderRequest = {...deepClone(bidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(bidderRequest), ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, clonedBidderRequest).data; expect(ortbRequest.regs.ext.us_privacy).to.equal(consentString); }); @@ -879,7 +879,7 @@ describe('stackadaptBidAdapter', function () { coppa: 1 } }; - const clonedBidderRequest = {...deepClone(bidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(bidderRequest), ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, clonedBidderRequest).data; expect(ortbRequest.regs.coppa).to.equal(1); }); @@ -891,7 +891,7 @@ describe('stackadaptBidAdapter', function () { gpp_sid: [9] } }; - const clonedBidderRequest = {...deepClone(bidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(bidderRequest), ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, clonedBidderRequest).data; expect(ortbRequest.regs.gpp).to.equal('DCACTA~1YAA'); expect(ortbRequest.regs.gpp_sid).to.eql([9]); @@ -916,7 +916,7 @@ describe('stackadaptBidAdapter', function () { clonedBidRequests[0].ortb2 = { source: { - ext: {schain: schain} + ext: { schain: schain } } }; clonedBidderRequest.bids = clonedBidRequests; @@ -924,7 +924,7 @@ describe('stackadaptBidAdapter', function () { // Add schain to bidderRequest as well clonedBidderRequest.ortb2 = { source: { - ext: {schain: schain} + ext: { schain: schain } } }; @@ -946,7 +946,7 @@ describe('stackadaptBidAdapter', function () { keywords: 'device={}' } }; - const mergedBidderRequest = {...bidderRequest, ortb2}; + const mergedBidderRequest = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, mergedBidderRequest).data; expect(ortbRequest.site.id).to.equal('144da00b-8309-4b2e-9482-4b3829c0b54a'); expect(ortbRequest.site.name).to.equal('game'); @@ -1017,7 +1017,7 @@ describe('stackadaptBidAdapter', function () { } }; - const bidderRequestMerged = {...bidderRequest, ortb2}; + const bidderRequestMerged = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, bidderRequestMerged).data; validateExtFirstPartyData(ortbRequest.site.ext) @@ -1032,7 +1032,7 @@ describe('stackadaptBidAdapter', function () { } }; - const bidderRequestMerged = {...bidderRequest, ortb2}; + const bidderRequestMerged = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, bidderRequestMerged).data; validateExtFirstPartyData(ortbRequest.user.ext) @@ -1066,7 +1066,7 @@ describe('stackadaptBidAdapter', function () { } }; - const bidderRequestMerged = {...bidderRequest, ortb2}; + const bidderRequestMerged = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, bidderRequestMerged).data; validateExtFirstPartyData(ortbRequest.app.ext) @@ -1081,7 +1081,7 @@ describe('stackadaptBidAdapter', function () { } }; - const bidderRequestMerged = {...bidderRequest, ortb2}; + const bidderRequestMerged = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, bidderRequestMerged).data; validateExtFirstPartyData(ortbRequest.device.ext) @@ -1096,7 +1096,7 @@ describe('stackadaptBidAdapter', function () { } }; - const bidderRequestMerged = {...bidderRequest, ortb2}; + const bidderRequestMerged = { ...bidderRequest, ortb2 }; const ortbRequest = spec.buildRequests(bidRequests, bidderRequestMerged).data; validateExtFirstPartyData(ortbRequest.pmp.ext) diff --git a/test/spec/modules/startioBidAdapter_spec.js b/test/spec/modules/startioBidAdapter_spec.js index 021c11e80dd..2b7269997aa 100644 --- a/test/spec/modules/startioBidAdapter_spec.js +++ b/test/spec/modules/startioBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/startioBidAdapter.js'; import { BANNER, VIDEO, NATIVE } from 'src/mediaTypes.js'; -import {deepClone} from '../../../src/utils.js'; +import { deepClone } from '../../../src/utils.js'; const DEFAULT_REQUEST_DATA = { adUnitCode: 'test-div', @@ -250,11 +250,11 @@ describe('Prebid Adapter: Startio', function () { it('should provide coppa', () => { let bidderRequest = deepClone(DEFAULT_BIDDER_REQUEST); - bidderRequest.ortb2 = {regs: {coppa: 0}}; + bidderRequest.ortb2 = { regs: { coppa: 0 } }; let request = spec.buildRequests([DEFAULT_REQUEST_DATA], bidderRequest)[0].data; expect(request.regs.coppa).to.equal(0); - bidderRequest.ortb2 = {regs: {coppa: 1}}; + bidderRequest.ortb2 = { regs: { coppa: 1 } }; request = spec.buildRequests([DEFAULT_REQUEST_DATA], bidderRequest)[0].data; expect(request.regs.coppa).to.equal(1); }); diff --git a/test/spec/modules/stnBidAdapter_spec.js b/test/spec/modules/stnBidAdapter_spec.js index 021005a90d6..d4634066bf7 100644 --- a/test/spec/modules/stnBidAdapter_spec.js +++ b/test/spec/modules/stnBidAdapter_spec.js @@ -2,9 +2,9 @@ import { expect } from 'chai'; import { spec } from 'modules/stnBidAdapter.js'; import { newBidder } from 'src/adapters/bidderFactory.js'; import { config } from 'src/config.js'; -import {BANNER, NATIVE, VIDEO} from '../../../src/mediaTypes.js'; +import { BANNER, NATIVE, VIDEO } from '../../../src/mediaTypes.js'; import * as utils from 'src/utils.js'; -import {decorateAdUnitsWithNativeParams} from '../../../src/native.js'; +import { decorateAdUnitsWithNativeParams } from '../../../src/native.js'; const ENDPOINT = 'https://hb.stngo.com/hb-multi'; const TEST_ENDPOINT = 'https://hb.stngo.com/hb-multi-test'; @@ -95,7 +95,7 @@ describe('stnAdapter', function () { 'mediaTypes': { 'banner': { 'sizes': [ - [ 300, 250 ] + [300, 250] ] }, 'video': { @@ -325,7 +325,7 @@ describe('stnAdapter', function () { }); it('should have us_privacy param if usPrivacy is available in the bidRequest', function () { - const bidderRequestWithUSP = Object.assign({uspConsent: '1YNN'}, bidderRequest); + const bidderRequestWithUSP = Object.assign({ uspConsent: '1YNN' }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithUSP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('us_privacy', '1YNN'); @@ -338,7 +338,7 @@ describe('stnAdapter', function () { }); it('should not send the gdpr param if gdprApplies is false in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: false}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: false } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gdpr'); @@ -346,7 +346,7 @@ describe('stnAdapter', function () { }); it('should send the gdpr param if gdprApplies is true in the bidRequest', function () { - const bidderRequestWithGDPR = Object.assign({gdprConsent: {gdprApplies: true, consentString: 'test-consent-string'}}, bidderRequest); + const bidderRequestWithGDPR = Object.assign({ gdprConsent: { gdprApplies: true, consentString: 'test-consent-string' } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGDPR); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gdpr', true); @@ -354,7 +354,7 @@ describe('stnAdapter', function () { }); it('should not send the gpp param if gppConsent is false in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: false}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: false }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.not.have.property('gpp'); @@ -362,7 +362,7 @@ describe('stnAdapter', function () { }); it('should send the gpp param if gppConsent is true in the bidRequest', function () { - const bidderRequestWithGPP = Object.assign({gppConsent: {gppString: 'test-consent-string', applicableSections: [7]}}, bidderRequest); + const bidderRequestWithGPP = Object.assign({ gppConsent: { gppString: 'test-consent-string', applicableSections: [7] } }, bidderRequest); const request = spec.buildRequests(bidRequests, bidderRequestWithGPP); expect(request.data.params).to.be.an('object'); expect(request.data.params).to.have.property('gpp', 'test-consent-string'); @@ -423,15 +423,15 @@ describe('stnAdapter', function () { 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, @@ -445,20 +445,20 @@ describe('stnAdapter', function () { 'sua': { 'platform': { 'brand': 'macOS', - 'version': [ '12', '4', '0' ] + 'version': ['12', '4', '0'] }, 'browsers': [ { 'brand': 'Chromium', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Google Chrome', - 'version': [ '106', '0', '5249', '119' ] + 'version': ['106', '0', '5249', '119'] }, { 'brand': 'Not;A=Brand', - 'version': [ '99', '0', '0', '0' ] + 'version': ['99', '0', '0', '0'] } ], 'mobile': 0, diff --git a/test/spec/modules/storageControl_spec.js b/test/spec/modules/storageControl_spec.js index a3fb571256b..2e6a146150e 100644 --- a/test/spec/modules/storageControl_spec.js +++ b/test/spec/modules/storageControl_spec.js @@ -1,4 +1,4 @@ -import {metadataRepository} from '../../../libraries/metadata/metadata.js'; +import { metadataRepository } from '../../../libraries/metadata/metadata.js'; import { checkDisclosure, dynamicDisclosureCollector, ENFORCE_ALIAS, ENFORCE_OFF, @@ -11,8 +11,8 @@ import { ACTIVITY_PARAM_COMPONENT_TYPE, ACTIVITY_PARAM_STORAGE_KEY, ACTIVITY_PARAM_STORAGE_TYPE } from '../../../src/activities/params.js'; -import {MODULE_TYPE_BIDDER} from '../../../src/activities/modules.js'; -import {STORAGE_TYPE_COOKIES} from '../../../src/storageManager.js'; +import { MODULE_TYPE_BIDDER } from '../../../src/activities/modules.js'; +import { STORAGE_TYPE_COOKIES } from '../../../src/storageManager.js'; describe('storageControl', () => { describe('getDisclosures', () => { @@ -186,31 +186,31 @@ describe('storageControl', () => { it('should allow when disclosed is null', () => { enforcement = ENFORCE_STRICT; - checkResult = {disclosed: null}; + checkResult = { disclosed: null }; expect(rule()).to.not.exist; }); it('should allow when there is no disclosure, but enforcement is off', () => { enforcement = ENFORCE_OFF; - checkResult = {disclosed: false, parent: false}; + checkResult = { disclosed: false, parent: false }; expect(rule()).to.not.exist; }); it('should allow when disclosed is true', () => { enforcement = ENFORCE_STRICT; - checkResult = {disclosed: true}; + checkResult = { disclosed: true }; expect(rule()).to.not.exist; }); it('should deny when enforcement is strict and disclosure is done by the aliased module', () => { enforcement = ENFORCE_STRICT; - checkResult = {disclosed: false, parent: true, reason: 'denied'}; - expect(rule()).to.eql({allow: false, reason: 'denied'}); + checkResult = { disclosed: false, parent: true, reason: 'denied' }; + expect(rule()).to.eql({ allow: false, reason: 'denied' }); }); it('should allow when enforcement is allowAliases and disclosure is done by the aliased module', () => { enforcement = ENFORCE_ALIAS; - checkResult = {disclosed: false, parent: true, reason: 'allowed'}; + checkResult = { disclosed: false, parent: true, reason: 'allowed' }; expect(rule()).to.not.exist; }); }); @@ -219,10 +219,10 @@ describe('storageControl', () => { let next, hook, getDisclosures; beforeEach(() => { next = sinon.stub(); - ({hook, getDisclosures} = dynamicDisclosureCollector()); + ({ hook, getDisclosures } = dynamicDisclosureCollector()); }); it('should collect and return disclosures', () => { - const disclosure = {identifier: 'mock', type: 'web', purposes: [1]}; + const disclosure = { identifier: 'mock', type: 'web', purposes: [1] }; hook(next, 'module', disclosure); sinon.assert.calledWith(next, 'module', disclosure); expect(getDisclosures()).to.eql([ @@ -233,8 +233,8 @@ describe('storageControl', () => { ]); }); it('should update disclosures for the same identifier', () => { - hook(next, 'module1', {identifier: 'mock', type: 'cookie', maxAgeSeconds: 10, cookieRefresh: true, purposes: [1]}); - hook(next, 'module2', {identifier: 'mock', type: 'cookie', maxAgeSeconds: 1, cookieRefresh: true, purposes: [2]}); + hook(next, 'module1', { identifier: 'mock', type: 'cookie', maxAgeSeconds: 10, cookieRefresh: true, purposes: [1] }); + hook(next, 'module2', { identifier: 'mock', type: 'cookie', maxAgeSeconds: 1, cookieRefresh: true, purposes: [2] }); expect(getDisclosures()).to.eql([{ disclosedBy: ['module1', 'module2'], identifier: 'mock', @@ -256,8 +256,8 @@ describe('storageControl', () => { }]) }) it('should treat web and cookie disclosures as separate', () => { - hook(next, 'module1', {identifier: 'mock', type: 'cookie', purposes: [1]}); - hook(next, 'module2', {identifier: 'mock', type: 'web', purposes: [2]}); + hook(next, 'module1', { identifier: 'mock', type: 'cookie', purposes: [1] }); + hook(next, 'module2', { identifier: 'mock', type: 'web', purposes: [2] }); expect(getDisclosures()).to.have.deep.members([ { disclosedBy: ['module1'], diff --git a/test/spec/modules/stroeerCoreBidAdapter_spec.js b/test/spec/modules/stroeerCoreBidAdapter_spec.js index 5458a33ec79..7c08dc5d118 100644 --- a/test/spec/modules/stroeerCoreBidAdapter_spec.js +++ b/test/spec/modules/stroeerCoreBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {assert} from 'chai'; -import {spec} from 'modules/stroeerCoreBidAdapter.js'; +import { assert } from 'chai'; +import { spec } from 'modules/stroeerCoreBidAdapter.js'; import * as utils from 'src/utils.js'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; import sinon from 'sinon'; describe('stroeerCore bid adapter', function () { @@ -120,7 +120,7 @@ describe('stroeerCore bid adapter', function () { const buildBidderResponse = () => ({ 'bids': [{ - 'bidId': 'bid1', 'cpm': 4.0, 'width': 300, 'height': 600, 'ad': '
tag1
', 'tracking': {'brandId': 123} + 'bidId': 'bid1', 'cpm': 4.0, 'width': 300, 'height': 600, 'ad': '
tag1
', 'tracking': { 'brandId': 123 } }, { 'bidId': 'bid2', 'cpm': 7.3, 'width': 728, 'height': 90, 'ad': '
tag2
' }] @@ -133,7 +133,7 @@ describe('stroeerCore bid adapter', function () { }); const createWindow = (href, params = {}) => { - const {parent, top, frameElement, placementElements = []} = params; + const { parent, top, frameElement, placementElements = [] } = params; const protocol = href.startsWith('https') ? 'https:' : 'http:'; const win = { @@ -196,7 +196,7 @@ describe('stroeerCore bid adapter', function () { const topWin = createWindow('http://www.abc.org/'); topWin.innerHeight = 800; - const midWin = createWindow('http://www.abc.org/', {parent: topWin, top: topWin, frameElement: createElement()}); + const midWin = createWindow('http://www.abc.org/', { parent: topWin, top: topWin, frameElement: createElement() }); midWin.innerHeight = 400; const win = createWindow('http://www.xyz.com/', { @@ -208,7 +208,7 @@ describe('stroeerCore bid adapter', function () { sandBox.stub(utils, 'getWindowSelf').returns(win); sandBox.stub(utils, 'getWindowTop').returns(topWin); - return {topWin, midWin, win}; + return { topWin, midWin, win }; } it('should support BANNER and VIDEO mediaType', function () { @@ -352,19 +352,19 @@ describe('stroeerCore bid adapter', function () { describe('should use custom url if provided', () => { const samples = [{ protocol: 'http:', - params: {sid: 'ODA=', host: 'other.com', port: '234', path: '/xyz'}, + params: { sid: 'ODA=', host: 'other.com', port: '234', path: '/xyz' }, expected: 'https://other.com:234/xyz' }, { protocol: 'https:', - params: {sid: 'ODA=', host: 'other.com', port: '234', path: '/xyz'}, + params: { sid: 'ODA=', host: 'other.com', port: '234', path: '/xyz' }, expected: 'https://other.com:234/xyz' }, { protocol: 'https:', - params: {sid: 'ODA=', host: 'other.com', port: '234', securePort: '871', path: '/xyz'}, + params: { sid: 'ODA=', host: 'other.com', port: '234', securePort: '871', path: '/xyz' }, expected: 'https://other.com:871/xyz' }, { - protocol: 'http:', params: {sid: 'ODA=', port: '234', path: '/xyz'}, expected: 'https://hb.adscale.de:234/xyz' - }, ]; + protocol: 'http:', params: { sid: 'ODA=', port: '234', path: '/xyz' }, expected: 'https://hb.adscale.de:234/xyz' + },]; samples.forEach(sample => { it(`should use ${sample.expected} as endpoint when given params ${JSON.stringify(sample.params)} and protocol ${sample.protocol}`, @@ -663,11 +663,11 @@ describe('stroeerCore bid adapter', function () { }); const gdprSamples = [ - {consentString: 'RG9ua2V5IEtvbmc=', gdprApplies: true}, - {consentString: 'UGluZyBQb25n', gdprApplies: false}, - {consentString: undefined, gdprApplies: true}, - {consentString: undefined, gdprApplies: false}, - {consentString: undefined, gdprApplies: undefined}, + { consentString: 'RG9ua2V5IEtvbmc=', gdprApplies: true }, + { consentString: 'UGluZyBQb25n', gdprApplies: false }, + { consentString: undefined, gdprApplies: true }, + { consentString: undefined, gdprApplies: false }, + { consentString: undefined, gdprApplies: undefined }, ]; gdprSamples.forEach((sample) => { it(`should add GDPR info ${JSON.stringify(sample)} when provided`, () => { @@ -736,19 +736,19 @@ describe('stroeerCore bid adapter', function () { getFloorStub1 .returns({}) - .withArgs({currency: 'EUR', mediaType: BANNER, size: '*'}) - .returns({currency: 'TRY', floor: 0.7}) - .withArgs({currency: 'EUR', mediaType: 'banner', size: [300, 600]}) - .returns({currency: 'TRY', floor: 1.3}) - .withArgs({currency: 'EUR', mediaType: 'banner', size: [160, 60]}) - .returns({currency: 'TRY', floor: 2.5}) + .withArgs({ currency: 'EUR', mediaType: BANNER, size: '*' }) + .returns({ currency: 'TRY', floor: 0.7 }) + .withArgs({ currency: 'EUR', mediaType: 'banner', size: [300, 600] }) + .returns({ currency: 'TRY', floor: 1.3 }) + .withArgs({ currency: 'EUR', mediaType: 'banner', size: [160, 60] }) + .returns({ currency: 'TRY', floor: 2.5 }) getFloorStub2 .returns({}) - .withArgs({currency: 'EUR', mediaType: 'banner', size: '*'}) - .returns({currency: 'USD', floor: 1.2}) - .withArgs({currency: 'EUR', mediaType: 'banner', size: [728, 90]}) - .returns({currency: 'USD', floor: 1.85}) + .withArgs({ currency: 'EUR', mediaType: 'banner', size: '*' }) + .returns({ currency: 'USD', floor: 1.2 }) + .withArgs({ currency: 'EUR', mediaType: 'banner', size: [728, 90] }) + .returns({ currency: 'USD', floor: 1.85 }) bidReq.bids[0].getFloor = getFloorStub1; bidReq.bids[1].getFloor = getFloorStub2; @@ -761,13 +761,13 @@ describe('stroeerCore bid adapter', function () { assert.nestedPropertyVal(firstBid, 'ban.fp.def', 0.7); assert.nestedPropertyVal(firstBid, 'ban.fp.cur', 'TRY'); - assert.deepNestedPropertyVal(firstBid, 'ban.fp.siz', [{w: 300, h: 600, p: 1.3}, {w: 160, h: 60, p: 2.5}]); + assert.deepNestedPropertyVal(firstBid, 'ban.fp.siz', [{ w: 300, h: 600, p: 1.3 }, { w: 160, h: 60, p: 2.5 }]); assert.isTrue(getFloorStub1.calledThrice); assert.nestedPropertyVal(secondBid, 'ban.fp.def', 1.2); assert.nestedPropertyVal(secondBid, 'ban.fp.cur', 'USD'); - assert.deepNestedPropertyVal(secondBid, 'ban.fp.siz', [{w: 728, h: 90, p: 1.85}]); + assert.deepNestedPropertyVal(secondBid, 'ban.fp.siz', [{ w: 728, h: 90, p: 1.85 }]); assert.isTrue(getFloorStub2.calledTwice); }); @@ -780,17 +780,17 @@ describe('stroeerCore bid adapter', function () { getFloorStub1 .returns({}) - .withArgs({currency: 'EUR', mediaType: 'video', size: '*'}) - .returns({currency: 'NZD', floor: 3.25}) - .withArgs({currency: 'EUR', mediaType: 'video', size: [640, 480]}) - .returns({currency: 'NZD', floor: 4.10}); + .withArgs({ currency: 'EUR', mediaType: 'video', size: '*' }) + .returns({ currency: 'NZD', floor: 3.25 }) + .withArgs({ currency: 'EUR', mediaType: 'video', size: [640, 480] }) + .returns({ currency: 'NZD', floor: 4.10 }); getFloorStub2 .returns({}) - .withArgs({currency: 'EUR', mediaType: 'video', size: '*'}) - .returns({currency: 'GBP', floor: 4.75}) - .withArgs({currency: 'EUR', mediaType: 'video', size: [1280, 720]}) - .returns({currency: 'GBP', floor: 6.50}) + .withArgs({ currency: 'EUR', mediaType: 'video', size: '*' }) + .returns({ currency: 'GBP', floor: 4.75 }) + .withArgs({ currency: 'EUR', mediaType: 'video', size: [1280, 720] }) + .returns({ currency: 'GBP', floor: 6.50 }) delete bidReq.bids[0].mediaTypes.banner; bidReq.bids[0].mediaTypes.video = { @@ -815,13 +815,13 @@ describe('stroeerCore bid adapter', function () { assert.nestedPropertyVal(firstBid, 'vid.fp.def', 3.25); assert.nestedPropertyVal(firstBid, 'vid.fp.cur', 'NZD'); - assert.deepNestedPropertyVal(firstBid, 'vid.fp.siz', [{w: 640, h: 480, p: 4.10}]); + assert.deepNestedPropertyVal(firstBid, 'vid.fp.siz', [{ w: 640, h: 480, p: 4.10 }]); assert.isTrue(getFloorStub1.calledTwice); assert.nestedPropertyVal(secondBid, 'vid.fp.def', 4.75); assert.nestedPropertyVal(secondBid, 'vid.fp.cur', 'GBP'); - assert.deepNestedPropertyVal(secondBid, 'vid.fp.siz', [{w: 1280, h: 720, p: 6.50}]); + assert.deepNestedPropertyVal(secondBid, 'vid.fp.siz', [{ w: 1280, h: 720, p: 6.50 }]); assert.isTrue(getFloorStub2.calledTwice); }); @@ -842,8 +842,8 @@ describe('stroeerCore bid adapter', function () { assert.nestedPropertyVal(firstBid, 'ban.fp', undefined); assert.nestedPropertyVal(secondBid, 'ban.fp', undefined); - assert.isTrue(getFloorSpy.calledWith({currency: 'EUR', mediaType: 'banner', size: '*'})); - assert.isTrue(getFloorSpy.calledWith({currency: 'EUR', mediaType: 'banner', size: [728, 90]})); + assert.isTrue(getFloorSpy.calledWith({ currency: 'EUR', mediaType: 'banner', size: '*' })); + assert.isTrue(getFloorSpy.calledWith({ currency: 'EUR', mediaType: 'banner', size: [728, 90] })); assert.isTrue(getFloorSpy.calledTwice); }); @@ -852,9 +852,9 @@ describe('stroeerCore bid adapter', function () { const getFloorStub = sinon.stub(); getFloorStub - .returns({currency: 'EUR', floor: 1.9}) - .withArgs({currency: 'EUR', mediaType: BANNER, size: [160, 60]}) - .returns({currency: 'EUR', floor: 2.7}); + .returns({ currency: 'EUR', floor: 1.9 }) + .withArgs({ currency: 'EUR', mediaType: BANNER, size: [160, 60] }) + .returns({ currency: 'EUR', floor: 2.7 }); bidReq.bids[0].getFloor = getFloorStub; @@ -865,7 +865,7 @@ describe('stroeerCore bid adapter', function () { assert.nestedPropertyVal(bid, 'ban.fp.def', 1.9); assert.nestedPropertyVal(bid, 'ban.fp.cur', 'EUR'); - assert.deepNestedPropertyVal(bid, 'ban.fp.siz', [{w: 160, h: 60, p: 2.7}]); + assert.deepNestedPropertyVal(bid, 'ban.fp.siz', [{ w: 160, h: 60, p: 2.7 }]); }); it('should add the DSA signals', () => { @@ -974,7 +974,7 @@ describe('stroeerCore bid adapter', function () { const serverRequestInfo = spec.buildRequests(bidReq.bids, bidReq); const sentOrtb2 = serverRequestInfo.data.ortb2; - assert.deepEqual(sentOrtb2, {site: {ext: ortb2.site.ext}}) + assert.deepEqual(sentOrtb2, { site: { ext: ortb2.site.ext } }) }); }); }); @@ -988,7 +988,7 @@ describe('stroeerCore bid adapter', function () { const invalidResponses = ['', ' ', ' ', undefined, null]; invalidResponses.forEach(sample => { it('should ignore invalid responses (\"' + sample + '\") response', () => { - const result = spec.interpretResponse({body: sample}); + const result = spec.interpretResponse({ body: sample }); assert.isArray(result); assert.lengthOf(result, 0); }); @@ -997,19 +997,19 @@ describe('stroeerCore bid adapter', function () { it('should interpret a standard response', () => { const bidderResponse = buildBidderResponse(); - const result = spec.interpretResponse({body: bidderResponse}); + const result = spec.interpretResponse({ body: bidderResponse }); assertStandardFieldsOnBannerBid(result[0], 'bid1', '
tag1
', 300, 600, 4); assertStandardFieldsOnBannerBid(result[1], 'bid2', '
tag2
', 728, 90, 7.3); }); it('should return empty array, when response contains no bids', () => { - const result = spec.interpretResponse({body: {bids: []}}); + const result = spec.interpretResponse({ body: { bids: [] } }); assert.deepStrictEqual(result, []); }); it('should interpret a video response', () => { const bidderResponse = buildBidderResponseWithVideo(); - const bidResponses = spec.interpretResponse({body: bidderResponse}); + const bidResponses = spec.interpretResponse({ body: bidderResponse }); const videoBidResponse = bidResponses[0]; assertStandardFieldsOnVideoBid(videoBidResponse, 'bid1', 'video', 800, 250, 4); }) @@ -1035,7 +1035,7 @@ describe('stroeerCore bid adapter', function () { }, }); - const result = spec.interpretResponse({body: response}); + const result = spec.interpretResponse({ body: response }); const firstBidMeta = result[0].meta; assert.deepPropertyVal(firstBidMeta, 'advertiserDomains', ['website.org', 'domain.com']); @@ -1074,13 +1074,13 @@ describe('stroeerCore bid adapter', function () { describe('when iframe option is enabled', () => { it('should perform user connect when there was a response', () => { const expectedUrl = 'https://js.adscale.de/pbsync.html'; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, ['']); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, ['']); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); it('should not perform user connect when there was no response', () => { - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, []); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, []); assert.deepStrictEqual(userSyncResponse, []); }); @@ -1089,26 +1089,26 @@ describe('stroeerCore bid adapter', function () { describe('and gdpr applies', () => { it('should place gdpr query param to the user sync url with value of 1', () => { const expectedUrl = 'https://js.adscale.de/pbsync.html?gdpr=1&gdpr_consent='; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, [''], {gdprApplies: true}); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, [''], { gdprApplies: true }); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); }); describe('and gdpr does not apply', () => { it('should place gdpr query param to the user sync url with zero value', () => { const expectedUrl = 'https://js.adscale.de/pbsync.html?gdpr=0&gdpr_consent='; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, [''], {gdprApplies: false}); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, [''], { gdprApplies: false }); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); describe('because consent does not specify it', () => { it('should place gdpr query param to the user sync url with zero value', () => { const expectedUrl = 'https://js.adscale.de/pbsync.html?gdpr=0&gdpr_consent='; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, [''], {}); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, [''], {}); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); }); }); @@ -1117,17 +1117,17 @@ describe('stroeerCore bid adapter', function () { it('should pass consent string to gdpr consent query param', () => { const consentString = 'consent_string'; const expectedUrl = `https://js.adscale.de/pbsync.html?gdpr=1&gdpr_consent=${consentString}`; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, [''], {gdprApplies: true, consentString}); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, [''], { gdprApplies: true, consentString }); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); it('should correctly escape invalid characters', () => { const consentString = 'consent ?stri&ng'; const expectedUrl = `https://js.adscale.de/pbsync.html?gdpr=1&gdpr_consent=consent%20%3Fstri%26ng`; - const userSyncResponse = spec.getUserSyncs({iframeEnabled: true}, [''], {gdprApplies: true, consentString}); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: true }, [''], { gdprApplies: true, consentString }); - assert.deepStrictEqual(userSyncResponse, [{type: 'iframe', url: expectedUrl}]); + assert.deepStrictEqual(userSyncResponse, [{ type: 'iframe', url: expectedUrl }]); }); }); }); @@ -1135,13 +1135,13 @@ describe('stroeerCore bid adapter', function () { describe('when iframe option is disabled', () => { it('should not perform user connect even when there was a response', () => { - const userSyncResponse = spec.getUserSyncs({iframeEnabled: false}, ['']); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: false }, ['']); assert.deepStrictEqual(userSyncResponse, []); }); it('should not perform user connect when there was no response', () => { - const userSyncResponse = spec.getUserSyncs({iframeEnabled: false}, []); + const userSyncResponse = spec.getUserSyncs({ iframeEnabled: false }, []); assert.deepStrictEqual(userSyncResponse, []); }); diff --git a/test/spec/modules/symitriDapRtdProvider_spec.js b/test/spec/modules/symitriDapRtdProvider_spec.js index f3deb840658..24adfde2ce3 100644 --- a/test/spec/modules/symitriDapRtdProvider_spec.js +++ b/test/spec/modules/symitriDapRtdProvider_spec.js @@ -1,4 +1,4 @@ -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; import { dapUtils, generateRealTimeData, @@ -6,10 +6,10 @@ import { onBidWonListener, storage, DAP_MAX_RETRY_TOKENIZE, DAP_SS_ID, DAP_TOKEN, DAP_MEMBERSHIP, DAP_ENCRYPTED_MEMBERSHIP } from 'modules/symitriDapRtdProvider.js'; -import {server} from 'test/mocks/xhr.js'; -import {hook} from '../../../src/hook.js'; +import { server } from 'test/mocks/xhr.js'; +import { hook } from '../../../src/hook.js'; import { EVENTS } from 'src/constants.js'; -const responseHeader = {'Content-Type': 'application/json'}; +const responseHeader = { 'Content-Type': 'application/json' }; const events = require('src/events'); @@ -90,10 +90,10 @@ describe('symitriDapRtdProvider', function() { 'identity': sampleIdentity } const cacheExpiry = Math.round(Date.now() / 1000.0) + 300; // in seconds - const sampleCachedToken = {'expires_at': cacheExpiry, 'token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..6buzBd2BjtgoyaNbHN8YnQ.l38avCfm3sYNy798-ETYOugz0cOx1cCkjACkAhYszxzrZ0sUJ0AiF-NdDXVTiTyp2Ih3vCWKzS0rKJ8lbS1zhyEVWVu91QwtwseM2fBbwA5ggAgBEo5wV-IXqDLPxVnxsPF0D3hP6cNCiH9Q2c-vULfsLhMhG5zvvZDPBbn4hUY5fKB8LoCBTF9rbuuWGYK1nramnb4AlS5UK82wBsHQea1Ou_Kp5wWCMNZ6TZk5qKIuRBfPIAhQblWvHECaHXkg1wyoM9VASs_yNhne7RR-qkwzbFiPFiMJibNOt9hF3_vPDJO5-06ZBjRTP1BllYGWxI-uQX6InzN18Wtun2WHqg.63sH0SNlIRcsK57v0pMujfB_nhU8Y5CuQbsHqH5MGoM'}; - const cachedEncryptedMembership = {'expires_at': cacheExpiry, 'encryptedSegments': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQifQ..IvnIUQDqWBVYIS0gbcE9bw.Z4NZGvtogWaWlGH4e-GdYKe_PUc15M2x3Bj85rMWsN1A17mIxQIMOfg2hsQ2tgieLu5LggWPmsFu1Wbph6P0k3kOu1dVReoIhOHzxw50rP0DLHKaEZ5mLMJ7Lcosvwh4miIfFuCHlsX7J0sFgOTAp0zGo1S_UsHLtev1JflhjoSB0AoX95ALbAnyctirPuLJM8gZ1vXTiZ01jpvucGyR1lM4cWjPOeD8jPtgwaPGgSRZXE-3X2Cqy7z4Giam5Uqu74LPWTBuKtUQTGyAXA5QJoP7xwTbsU4O1f69lu3fWNqC92GijeTH1A4Zd_C-WXxWuQlDEURjlkWQoaqTHka2OqlnwukEQIf_v0r5KQQX64CTLhEUH91jeD0-E9ClcIP7pwOLxxqiKoaBmx8Mrnm_6Agj5DtTA1rusy3AL63sI_rsUxrmLrVt0Wft4aCfRkW8QpQxu8clFdOmce0NNCGeBCyCPVw9d9izrILlXJ6rItU2cpFrcbz8uw2otamF5eOFCOY3IzHedWVNNuKHFIUVC_xYSlsYvQ8f2QIP1eiMbmukcuPzmTzjw1h1_7IKaj-jJkXrnrY-TdDgX_4-_Z3rmbpXK2yTR7dBrsg-ubqFbgbKic1b4zlQEO_LbBlgPl3DYdWEuJ8CY2NUt1GfpATQGsufS2FTY1YGw_gkPe3q04l_cgLafDoxHvHh_t_0ZgPjciW82gThB_kN4RP7Mc3krVcXl_P6N1VbV07xyx0hCyVsrrxbLslI8q9wYDiLGci7mNmByM5j7SXV9jPwwPkHtn0HfMJlw2PFbIDPjgG3h7sOyLcBIJTTvuUIgpHPIkRWLIl_4FlIucXbJ7orW2nt5BWleBVHgumzGcnl9ZNcZb3W-dsdYPSOmuj0CY28MRTP2oJ1rzLInbDDpIRffJBtR7SS4nYyy7Vi09PtBigod5YNz1Q0WDSJxr8zeH_aKFaXInw7Bfo_U0IAcLiRgcT0ogsMLeQRjRFy27mr4XNJv3NtHhbdjDAwF2aClCktXyXbQaVdsPH2W71v6m2Q9rB5GQWOktw2s5f-4N1-_EBPGq6TgjF-aJZP22MJVwp1pimT50DfOzoeEqDwi862NNwNNoHmcObH0ZfwAXlhRxsgupNBe20-MNNABj2Phlfv4DUrtQbMdfCnNiypzNCmoTb7G7c_o5_JUwoV_GVkwUtvmi_IUm05P4GeMASSUw8zDKVRAj9h31C2cabM8RjMHGhkbCWpUP2pcz9zlJ7Y76Dh3RLnctfTw7DG9U4w4UlaxNZOgLUiSrGwfyapuSiuGUpuOJkBBLiHmEqAGI5C8oJpcVRccNlHxJAYowgXyFopD5Fr-FkXmv8KMkS0h5C9F6KihmDt5sqDD0qnjM0hHJgq01l7wjVnhEmPpyD-6auFQ-xDnbh1uBOJ_0gCVbRad--FSa5p-dXenggegRxOvZXJ0iAtM6Fal5Og-RCjexIHa9WhVbXhQBJpkSTWwAajZJ64eQ.yih49XB51wE-Xob7COT9OYqBrzBmIMVCQbLFx2UdzkI'}; - const cachedMembership = {'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13']}; - const cachedMembershipWithDeals = {'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13'], 'deals': ['{"id":"DEMODEAL555","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL111","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL123","bidfloor":5.0,"at":1,"guar":0}']}; + const sampleCachedToken = { 'expires_at': cacheExpiry, 'token': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..6buzBd2BjtgoyaNbHN8YnQ.l38avCfm3sYNy798-ETYOugz0cOx1cCkjACkAhYszxzrZ0sUJ0AiF-NdDXVTiTyp2Ih3vCWKzS0rKJ8lbS1zhyEVWVu91QwtwseM2fBbwA5ggAgBEo5wV-IXqDLPxVnxsPF0D3hP6cNCiH9Q2c-vULfsLhMhG5zvvZDPBbn4hUY5fKB8LoCBTF9rbuuWGYK1nramnb4AlS5UK82wBsHQea1Ou_Kp5wWCMNZ6TZk5qKIuRBfPIAhQblWvHECaHXkg1wyoM9VASs_yNhne7RR-qkwzbFiPFiMJibNOt9hF3_vPDJO5-06ZBjRTP1BllYGWxI-uQX6InzN18Wtun2WHqg.63sH0SNlIRcsK57v0pMujfB_nhU8Y5CuQbsHqH5MGoM' }; + const cachedEncryptedMembership = { 'expires_at': cacheExpiry, 'encryptedSegments': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoic29tZXNlY3JldGludmF1bHQifQ..IvnIUQDqWBVYIS0gbcE9bw.Z4NZGvtogWaWlGH4e-GdYKe_PUc15M2x3Bj85rMWsN1A17mIxQIMOfg2hsQ2tgieLu5LggWPmsFu1Wbph6P0k3kOu1dVReoIhOHzxw50rP0DLHKaEZ5mLMJ7Lcosvwh4miIfFuCHlsX7J0sFgOTAp0zGo1S_UsHLtev1JflhjoSB0AoX95ALbAnyctirPuLJM8gZ1vXTiZ01jpvucGyR1lM4cWjPOeD8jPtgwaPGgSRZXE-3X2Cqy7z4Giam5Uqu74LPWTBuKtUQTGyAXA5QJoP7xwTbsU4O1f69lu3fWNqC92GijeTH1A4Zd_C-WXxWuQlDEURjlkWQoaqTHka2OqlnwukEQIf_v0r5KQQX64CTLhEUH91jeD0-E9ClcIP7pwOLxxqiKoaBmx8Mrnm_6Agj5DtTA1rusy3AL63sI_rsUxrmLrVt0Wft4aCfRkW8QpQxu8clFdOmce0NNCGeBCyCPVw9d9izrILlXJ6rItU2cpFrcbz8uw2otamF5eOFCOY3IzHedWVNNuKHFIUVC_xYSlsYvQ8f2QIP1eiMbmukcuPzmTzjw1h1_7IKaj-jJkXrnrY-TdDgX_4-_Z3rmbpXK2yTR7dBrsg-ubqFbgbKic1b4zlQEO_LbBlgPl3DYdWEuJ8CY2NUt1GfpATQGsufS2FTY1YGw_gkPe3q04l_cgLafDoxHvHh_t_0ZgPjciW82gThB_kN4RP7Mc3krVcXl_P6N1VbV07xyx0hCyVsrrxbLslI8q9wYDiLGci7mNmByM5j7SXV9jPwwPkHtn0HfMJlw2PFbIDPjgG3h7sOyLcBIJTTvuUIgpHPIkRWLIl_4FlIucXbJ7orW2nt5BWleBVHgumzGcnl9ZNcZb3W-dsdYPSOmuj0CY28MRTP2oJ1rzLInbDDpIRffJBtR7SS4nYyy7Vi09PtBigod5YNz1Q0WDSJxr8zeH_aKFaXInw7Bfo_U0IAcLiRgcT0ogsMLeQRjRFy27mr4XNJv3NtHhbdjDAwF2aClCktXyXbQaVdsPH2W71v6m2Q9rB5GQWOktw2s5f-4N1-_EBPGq6TgjF-aJZP22MJVwp1pimT50DfOzoeEqDwi862NNwNNoHmcObH0ZfwAXlhRxsgupNBe20-MNNABj2Phlfv4DUrtQbMdfCnNiypzNCmoTb7G7c_o5_JUwoV_GVkwUtvmi_IUm05P4GeMASSUw8zDKVRAj9h31C2cabM8RjMHGhkbCWpUP2pcz9zlJ7Y76Dh3RLnctfTw7DG9U4w4UlaxNZOgLUiSrGwfyapuSiuGUpuOJkBBLiHmEqAGI5C8oJpcVRccNlHxJAYowgXyFopD5Fr-FkXmv8KMkS0h5C9F6KihmDt5sqDD0qnjM0hHJgq01l7wjVnhEmPpyD-6auFQ-xDnbh1uBOJ_0gCVbRad--FSa5p-dXenggegRxOvZXJ0iAtM6Fal5Og-RCjexIHa9WhVbXhQBJpkSTWwAajZJ64eQ.yih49XB51wE-Xob7COT9OYqBrzBmIMVCQbLFx2UdzkI' }; + const cachedMembership = { 'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13'] }; + const cachedMembershipWithDeals = { 'expires_at': cacheExpiry, 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..QwvU5h0NVJYaJbs5EqWCKA.XNaJHSlnsH8P-yBIr3gIEqavLONWDIFyj7QCHFwJVkwXH_EYkxrk0_26b0uMPzfJp5URnqxKZusMH9DzEJsmj8EMrKQv1y3IYYMsW5_0BdP5bcAWfG6fzOqtMOwLiYRkYiQOqn1ZVGzhovheHWEmNr2_oCY0LvAr3iN1eG_K-l-bBKvBWnwvuuGKquUfCqO8NMMq6wtkecEXM9blqFRZ7oNYmW2aIG7qcHUsrUW7HMr9Ev2Ik0sIeEUsOYrgf_X_VA64RgKSTRugS9FupMv1p54JkHokwduF9pOFmW8QLQi8itFogKGbbgvOTNnmahxQUX5FcrjjYLqHwKqC8htLdlHnO5LWU9l4A7vLXrRurvoSnh0cAJy0GsdoyEwTqR9bwVFHoPquxlJjQ4buEd7PIxpBj9Qg9oOPH3b2upbMTu5CQ9oj526eXPhP5G54nwGklm2AZ3Vggd7jCQJn45Jjiq0iIfsXAtpqS2BssCLBN8WhmUTnStK8m5sux6WUBdrpDESQjPj-EEHVS-DB5rA7icRUh6EzRxzen2rndvHvnwVhSG_l6cwPYuJ0HE0KBmYHOoqNpKwzoGiKFHrf4ReA06iWB3V2TEGJucGujhtQ9_18WwHCeJ1XtQiiO1eqa3tp5MwAbFXawVFl3FFOBgadrPyvGmkmUJ6FCLU2MSwHiYZmANMnJsokFX_6DwoAgO3U_QnvEHIVSvefc7ReeJ8fBDdmrH3LtuLrUpXsvLvEIMQdWQ_SXhjKIi7tOODR8CfrhUcdIjsp3PZs1DpuOcDB6YJKbGnKZTluLUJi3TyHgyi-DHXdTm-jSE5i_DYJGW-t2Gf23FoQhexv4q7gdrfsKfcRJNrZLp6Gd6jl4zHhUtY.nprKBsy9taQBk6dCPbA7BFF0CiGhQOEF_MazZ2bedqk', 'cohorts': ['9', '11', '13'], 'deals': ['{"id":"DEMODEAL555","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL111","bidfloor":5.0,"at":1,"guar":0}', '{"id":"DEMODEAL123","bidfloor":5.0,"at":1,"guar":0}'] }; const rtdUserObj = { name: 'www.dataprovider3.com', ext: { @@ -154,7 +154,7 @@ describe('symitriDapRtdProvider', function() { let ortb2, bidConfig; beforeEach(function() { - bidConfig = {ortb2Fragments: {}}; + bidConfig = { ortb2Fragments: {} }; ortb2 = bidConfig.ortb2Fragments.global = {}; config.resetConfig(); storage.removeDataFromLocalStorage(DAP_TOKEN); @@ -204,7 +204,7 @@ describe('symitriDapRtdProvider', function() { try { expect(ortb2).to.eql({}); dapUtils.callDapAPIs(bidConfig, () => {}, cmoduleConfig, {}); - const membership = {'cohorts': ['9', '11', '13'], 'said': 'sample-said'} + const membership = { 'cohorts': ['9', '11', '13'], 'said': 'sample-said' } const membershipRequest = server.requests[0]; membershipRequest.respond(200, responseHeader, JSON.stringify(membership)); const tokenWithExpiry = 'Sample-token-with-exp' @@ -234,7 +234,7 @@ describe('symitriDapRtdProvider', function() { tokenizeRequest.requestHeaders['Content-Type'].should.equal('application/json'); responseHeader['Symitri-DAP-Token'] = tokenWithExpiry; tokenizeRequest.respond(200, responseHeader, JSON.stringify(tokenWithExpiry)); - const data = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, emoduleConfig.params.segtax); + const data = dapUtils.dapGetEncryptedRtdObj({ 'encryptedSegments': encMembership }, emoduleConfig.params.segtax); expect(ortb2.user.data).to.deep.include.members(data.rtd.ortb2.user.data); } finally { dapExtractExpiryFromTokenStub.restore(); @@ -447,7 +447,7 @@ describe('symitriDapRtdProvider', function() { segtax: 708 }; expect(dapUtils.dapRefreshMembership(ortb2, config, 'token', onDone)).to.equal(undefined) - const membership = {cohorts: ['1', '5', '7']} + const membership = { cohorts: ['1', '5', '7'] } expect(dapUtils.dapGetRtdObj(membership, config.segtax)).to.not.equal(undefined); }); }); @@ -518,7 +518,7 @@ describe('symitriDapRtdProvider', function() { const request = server.requests[0]; responseHeader['Symitri-DAP-Token'] = encMembership; request.respond(200, responseHeader, encMembership); - const rtdObj = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, 710) + const rtdObj = dapUtils.dapGetEncryptedRtdObj({ 'encryptedSegments': encMembership }, 710) expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); expect(JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)).expires_at).to.equal(expiry); }); @@ -529,7 +529,7 @@ describe('symitriDapRtdProvider', function() { const request = server.requests[0]; responseHeader['Symitri-DAP-Token'] = encMembership; request.respond(200, responseHeader, encMembership); - const rtdObj = dapUtils.dapGetEncryptedRtdObj({'encryptedSegments': encMembership}, 710) + const rtdObj = dapUtils.dapGetEncryptedRtdObj({ 'encryptedSegments': encMembership }, 710) expect(ortb2.user.data).to.deep.include.members(rtdObj.rtd.ortb2.user.data); expect(JSON.parse(storage.getDataFromLocalStorage(DAP_ENCRYPTED_MEMBERSHIP)).expires_at).to.equal(1643830630); }); @@ -556,7 +556,7 @@ describe('symitriDapRtdProvider', function() { describe('dapRefreshMembership test', function () { it('test dapRefreshMembership success response', function () { - const membership = {'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..17wnrhz6FbWx0Cf6LXpm1A.m9PKVCradk3CZokNKzVHzE06TOqiXYeijgxTQUiQy5Syx-yicnO8DyYX6zQ6rgPcNgUNRt4R4XE5MXuK0laUVQJr9yc9g3vUfQfw69OMYGW_vRlLMPzoNOhF2c4gSyfkRrLr7C0qgALmZO1D11sPflaCTNmO7pmZtRaCOB5buHoWcQhp1bUSJ09DNDb31dX3llimPwjNGSrUhyq_EZl4HopnnjxbM4qVNMY2G_43C_idlVOvbFoTxcDRATd-6MplJoIOIHQLDZEetpIOVcbEYN9gQ_ndBISITwuu5YEgs5C_WPHA25nm6e4BT5R-tawSA8yPyQAupqE8gk4ZWq_2-T0cqyTstIHrMQnZ_vysYN7h6bkzE-KeZRk7GMtySN87_fiu904hLD9QentGegamX6UAbVqQh7Htj7SnMHXkEenjxXAM5mRqQvNCTlw8k-9-VPXs-vTcKLYP8VFf8gMOmuYykgWac1gX-svyAg-24mo8cUbqcsj9relx4Qj5HiXUVyDMBZxK-mHZi-Xz6uv9GlggcsjE13DSszar-j2OetigpdibnJIxRZ-4ew3-vlvZ0Dul3j0LjeWURVBWYWfMjuZ193G7lwR3ohh_NzlNfwOPBK_SYurdAnLh7jJgTW-lVLjH2Dipmi9JwX9s03IQq9opexAn7hlM9oBI6x5asByH8JF8WwZ5GhzDjpDwpSmHPQNGFRSyrx_Sh2CPWNK6C1NJmLkyqAtJ5iw0_al7vPDQyZrKXaLTjBCUnbpJhUZ8dUKtWLzGPjzFXp10muoDIutd1NfyKxk1aWGhx5aerYuLdywv6cT_M8RZTi8924NGj5VA30V5OvEwLLyX93eDhntXZSCbkPHpAfiRZNGXrPY.GhCbWGQz11mIRD4uPKmoAuFXDH7hGnils54zg7N7-TU'} + const membership = { 'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIn0..17wnrhz6FbWx0Cf6LXpm1A.m9PKVCradk3CZokNKzVHzE06TOqiXYeijgxTQUiQy5Syx-yicnO8DyYX6zQ6rgPcNgUNRt4R4XE5MXuK0laUVQJr9yc9g3vUfQfw69OMYGW_vRlLMPzoNOhF2c4gSyfkRrLr7C0qgALmZO1D11sPflaCTNmO7pmZtRaCOB5buHoWcQhp1bUSJ09DNDb31dX3llimPwjNGSrUhyq_EZl4HopnnjxbM4qVNMY2G_43C_idlVOvbFoTxcDRATd-6MplJoIOIHQLDZEetpIOVcbEYN9gQ_ndBISITwuu5YEgs5C_WPHA25nm6e4BT5R-tawSA8yPyQAupqE8gk4ZWq_2-T0cqyTstIHrMQnZ_vysYN7h6bkzE-KeZRk7GMtySN87_fiu904hLD9QentGegamX6UAbVqQh7Htj7SnMHXkEenjxXAM5mRqQvNCTlw8k-9-VPXs-vTcKLYP8VFf8gMOmuYykgWac1gX-svyAg-24mo8cUbqcsj9relx4Qj5HiXUVyDMBZxK-mHZi-Xz6uv9GlggcsjE13DSszar-j2OetigpdibnJIxRZ-4ew3-vlvZ0Dul3j0LjeWURVBWYWfMjuZ193G7lwR3ohh_NzlNfwOPBK_SYurdAnLh7jJgTW-lVLjH2Dipmi9JwX9s03IQq9opexAn7hlM9oBI6x5asByH8JF8WwZ5GhzDjpDwpSmHPQNGFRSyrx_Sh2CPWNK6C1NJmLkyqAtJ5iw0_al7vPDQyZrKXaLTjBCUnbpJhUZ8dUKtWLzGPjzFXp10muoDIutd1NfyKxk1aWGhx5aerYuLdywv6cT_M8RZTi8924NGj5VA30V5OvEwLLyX93eDhntXZSCbkPHpAfiRZNGXrPY.GhCbWGQz11mIRD4uPKmoAuFXDH7hGnils54zg7N7-TU' } dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone); const request = server.requests[0]; request.respond(200, responseHeader, JSON.stringify(membership)); @@ -565,7 +565,7 @@ describe('symitriDapRtdProvider', function() { }); it('test dapRefreshMembership success response with exp claim', function () { - const membership = {'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIiwiZXhwIjoxNjQ3OTcxNTU4fQ..ptdM5WO-62ypXlKxFXD4FQ.waEo9MHS2NYQCi-zh_p6HgT9BdqGyQbBq4GfGLfsay4nRBgICsTS-VkV6e7xx5U1T8BgpKkRJIZBwTOY5Pkxk9FpK5nnffDSEljRrp1LXLCkNP4qwrlqHInFbZsonNWW4_mW-7aUPlTwIsTbfjTuyHdXHeQa1ALrwFFFWE7QUmPNd2RsHjDwUsxlJPEb5TnHn5W0Mgo_PQZaxvhJInMbxPgtJLoqnJvOqCBEoQY7au7ALZL_nWK8XIwPMF19J7Z3cBg9vQInhr_E3rMdQcAFHEzYfgoNcIYCCR0t1UOqUE3HNtX-E64kZAYKWdlsBb9eW5Gj9hHYyPNL_4Hntjg5eLXGpsocMg0An-qQKGC6hkrxKzeM-GrjpvSaQLNs4iqDpHUtzA02LW_vkLkMNRUiyXVJ3FUZwfyq6uHSRKWZ6UFdAfL0rfJ8q8x8Ll-qJO2Jfyvidlsi9FIs7x1WJrvDCKepfAQM1UXRTonrQljFBAk83PcL2bmWuJDgJZ0lWS4VnZbIf6A7fDourmkDxdVRptvQq5nSjtzCA6whRw0-wGz8ehNJsaJw9H_nG9k4lRKs7A5Lqsyy7TVFrAPjnA_Q1a2H6xF2ULxrtIqoNqdX7k9RjowEZSQlZgZUOAmI4wzjckdcSyC_pUlYBMcBwmlld34mmOJe9EBHAxjdci7Q_9lvj1HTcwGDcQITXnkW9Ux5Jkt9Naw-IGGrnEIADaT2guUAto8W_Gb05TmwHSd6DCmh4zepQCbqeVe6AvPILtVkTgsTTo27Q-NvS7h-XtthJy8425j5kqwxxpZFJ0l0ytc6DUyNCLJXuxi0JFU6-LoSXcROEMVrHa_Achufr9vHIELwacSAIHuwseEvg_OOu1c1WYEwZH8ynBLSjqzy8AnDj24hYgA0YanPAvDqacrYrTUFqURbHmvcQqLBTcYa_gs7uDx4a1EjtP_NvHRlvCgGAaASrjGMhTX8oJxlTqahhQ.pXm-7KqnNK8sbyyczwkVYhcjgiwkpO8LjBBVw4lcyZE'}; + const membership = { 'cohorts': ['9', '11', '13'], 'said': 'eyJhbGciOiJkaXIiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2Iiwia2lkIjoicGFzc3dvcmQxIiwiZXhwIjoxNjQ3OTcxNTU4fQ..ptdM5WO-62ypXlKxFXD4FQ.waEo9MHS2NYQCi-zh_p6HgT9BdqGyQbBq4GfGLfsay4nRBgICsTS-VkV6e7xx5U1T8BgpKkRJIZBwTOY5Pkxk9FpK5nnffDSEljRrp1LXLCkNP4qwrlqHInFbZsonNWW4_mW-7aUPlTwIsTbfjTuyHdXHeQa1ALrwFFFWE7QUmPNd2RsHjDwUsxlJPEb5TnHn5W0Mgo_PQZaxvhJInMbxPgtJLoqnJvOqCBEoQY7au7ALZL_nWK8XIwPMF19J7Z3cBg9vQInhr_E3rMdQcAFHEzYfgoNcIYCCR0t1UOqUE3HNtX-E64kZAYKWdlsBb9eW5Gj9hHYyPNL_4Hntjg5eLXGpsocMg0An-qQKGC6hkrxKzeM-GrjpvSaQLNs4iqDpHUtzA02LW_vkLkMNRUiyXVJ3FUZwfyq6uHSRKWZ6UFdAfL0rfJ8q8x8Ll-qJO2Jfyvidlsi9FIs7x1WJrvDCKepfAQM1UXRTonrQljFBAk83PcL2bmWuJDgJZ0lWS4VnZbIf6A7fDourmkDxdVRptvQq5nSjtzCA6whRw0-wGz8ehNJsaJw9H_nG9k4lRKs7A5Lqsyy7TVFrAPjnA_Q1a2H6xF2ULxrtIqoNqdX7k9RjowEZSQlZgZUOAmI4wzjckdcSyC_pUlYBMcBwmlld34mmOJe9EBHAxjdci7Q_9lvj1HTcwGDcQITXnkW9Ux5Jkt9Naw-IGGrnEIADaT2guUAto8W_Gb05TmwHSd6DCmh4zepQCbqeVe6AvPILtVkTgsTTo27Q-NvS7h-XtthJy8425j5kqwxxpZFJ0l0ytc6DUyNCLJXuxi0JFU6-LoSXcROEMVrHa_Achufr9vHIELwacSAIHuwseEvg_OOu1c1WYEwZH8ynBLSjqzy8AnDj24hYgA0YanPAvDqacrYrTUFqURbHmvcQqLBTcYa_gs7uDx4a1EjtP_NvHRlvCgGAaASrjGMhTX8oJxlTqahhQ.pXm-7KqnNK8sbyyczwkVYhcjgiwkpO8LjBBVw4lcyZE' }; dapUtils.dapRefreshMembership(ortb2, sampleConfig, sampleCachedToken.token, onDone); const request = server.requests[0]; request.respond(200, responseHeader, JSON.stringify(membership)); @@ -597,7 +597,7 @@ describe('symitriDapRtdProvider', function() { it('test dapGetEncryptedMembershipFromLocalStorage function with invalid cache', function () { const expiry = Math.round(Date.now() / 1000.0) - 100; // in seconds - const encMembership = {'expiry': expiry, 'encryptedSegments': cachedEncryptedMembership.encryptedSegments} + const encMembership = { 'expiry': expiry, 'encryptedSegments': cachedEncryptedMembership.encryptedSegments } storage.setDataInLocalStorage(DAP_ENCRYPTED_MEMBERSHIP, JSON.stringify(encMembership)) expect(dapUtils.dapGetEncryptedMembershipFromLocalStorage()).to.equal(null); }); @@ -644,11 +644,11 @@ describe('symitriDapRtdProvider', function() { }); it('USP consent present and user have not been provided with option to opt out', function () { - expect(symitriDapRtdSubmodule.init(null, {'usp': '1NYY'})).to.equal(false); + expect(symitriDapRtdSubmodule.init(null, { 'usp': '1NYY' })).to.equal(false); }); it('USP consent present and user have not opted out', function () { - expect(symitriDapRtdSubmodule.init(null, {'usp': '1YNY'})).to.equal(true); + expect(symitriDapRtdSubmodule.init(null, { 'usp': '1YNY' })).to.equal(true); }); }); @@ -695,7 +695,7 @@ describe('symitriDapRtdProvider', function() { }); describe('onBidResponseEvent', function () { - const bidResponse = {adId: 'ad_123', bidder: 'test_bidder', bidderCode: 'test_bidder_code', cpm: '1.5', creativeId: 'creative_123', dealId: 'DEMODEAL555', mediaType: 'banner', responseTimestamp: '1725892736147', ad: ''}; + const bidResponse = { adId: 'ad_123', bidder: 'test_bidder', bidderCode: 'test_bidder_code', cpm: '1.5', creativeId: 'creative_123', dealId: 'DEMODEAL555', mediaType: 'banner', responseTimestamp: '1725892736147', ad: '' }; const url = emoduleConfig.params.pixelUrl + '?token=' + sampleCachedToken.token + '&ad_id=' + bidResponse.adId + '&bidder=' + bidResponse.bidder + '&bidder_code=' + bidResponse.bidderCode + '&cpm=' + bidResponse.cpm + '&creative_id=' + bidResponse.creativeId + '&deal_id=' + bidResponse.dealId + '&media_type=' + bidResponse.mediaType + '&response_timestamp=' + bidResponse.responseTimestamp; const adPixel = `${bidResponse.ad}"'; @@ -428,7 +428,7 @@ describe('teadsBidAdapter', () => { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }, }, }, @@ -765,20 +765,20 @@ describe('teadsBidAdapter', () => { source: 2, platform: { brand: 'macOS', - version: [ '12', '4', '0' ] + version: ['12', '4', '0'] }, browsers: [ { brand: 'Chromium', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Google Chrome', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Not;A=Brand', - version: [ '99', '0', '0', '0' ] + version: ['99', '0', '0', '0'] } ], mobile: 0, @@ -798,20 +798,20 @@ describe('teadsBidAdapter', () => { source: 2, platform: { brand: 'macOS', - version: [ '12', '4', '0' ] + version: ['12', '4', '0'] }, browsers: [ { brand: 'Chromium', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Google Chrome', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Not;A=Brand', - version: [ '99', '0', '0', '0' ] + version: ['99', '0', '0', '0'] } ], mobile: 0, @@ -863,7 +863,7 @@ describe('teadsBidAdapter', () => { const toEid = (sourceId, value) => ({ source: sourceId, - uids: [{id: value}] + uids: [{ id: value }] }) describe('User IDs', function () { diff --git a/test/spec/modules/teadsIdSystem_spec.js b/test/spec/modules/teadsIdSystem_spec.js index ed4ea887d5b..cae9d6e7b51 100644 --- a/test/spec/modules/teadsIdSystem_spec.js +++ b/test/spec/modules/teadsIdSystem_spec.js @@ -8,7 +8,7 @@ import { getGdprConsentString, getCookieExpirationDate, getTimestampFromDays, getCcpaConsentString } from 'modules/teadsIdSystem.js'; -import {server} from 'test/mocks/xhr.js'; +import { server } from 'test/mocks/xhr.js'; import * as utils from '../../../src/utils.js'; const FP_TEADS_ID_COOKIE_NAME = '_tfpvi'; @@ -234,7 +234,7 @@ describe('TeadsIdSystem', function () { callback(callbackSpy); const request = server.requests[0]; expect(request.url).to.include(teadsUrl); - request.respond(200, {'Content-Type': 'application/json'}, teadsCookieIdSent); + request.respond(200, { 'Content-Type': 'application/json' }, teadsCookieIdSent); expect(callbackSpy.lastCall.lastArg).to.deep.equal(teadsCookieIdSent); }); @@ -248,7 +248,7 @@ describe('TeadsIdSystem', function () { }); const request = server.requests[0]; - request.respond(200, {'Content-Type': 'application/json'}, teadsCookieIdSent); + request.respond(200, { 'Content-Type': 'application/json' }, teadsCookieIdSent); const cookiesMaxAge = getTimestampFromDays(365); // 1 year const expirationCookieDate = getCookieExpirationDate(cookiesMaxAge); @@ -265,7 +265,7 @@ describe('TeadsIdSystem', function () { }); const request = server.requests[0]; - request.respond(200, {'Content-Type': 'application/json'}, ''); + request.respond(200, { 'Content-Type': 'application/json' }, ''); expect(setCookieStub.calledWith(FP_TEADS_ID_COOKIE_NAME, '', EXPIRED_COOKIE_DATE)).to.be.true; }); diff --git a/test/spec/modules/tealBidAdapter_spec.js b/test/spec/modules/tealBidAdapter_spec.js index 12e04d0b4d5..1452c7689f8 100644 --- a/test/spec/modules/tealBidAdapter_spec.js +++ b/test/spec/modules/tealBidAdapter_spec.js @@ -205,7 +205,7 @@ const buildRequest = (params) => { describe('Teal Bid Adaper', function () { describe('buildRequests', () => { - const {data, url} = buildRequest(); + const { data, url } = buildRequest(); it('should give the correct URL', () => { expect(url).equal(`https://${PBS_HOST}/openrtb2/auction`); }); @@ -222,7 +222,7 @@ describe('Teal Bid Adaper', function () { }); }); describe('buildRequests with subAccount', () => { - const {data} = buildRequest({ subAccount: SUB_ACCOUNT }); + const { data } = buildRequest({ subAccount: SUB_ACCOUNT }); it('should set the correct stored request ids', () => { expect(data.ext.prebid.storedrequest.id).equal(SUB_ACCOUNT); }); diff --git a/test/spec/modules/temedyaBidAdapter_spec.js b/test/spec/modules/temedyaBidAdapter_spec.js index 971b4d4d4bb..ec84ab9c3f1 100644 --- a/test/spec/modules/temedyaBidAdapter_spec.js +++ b/test/spec/modules/temedyaBidAdapter_spec.js @@ -1,5 +1,5 @@ -import {expect} from 'chai'; -import {spec} from 'modules/temedyaBidAdapter.js'; +import { expect } from 'chai'; +import { spec } from 'modules/temedyaBidAdapter.js'; import * as utils from 'src/utils.js'; const ENDPOINT_URL = 'https://adm.vidyome.com/'; @@ -165,7 +165,7 @@ describe('temedya adapter', function() { } ]; const request = spec.buildRequests(bidRequests)[0]; - const result = spec.interpretResponse({body: response}, request); + const result = spec.interpretResponse({ body: response }, request); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); expect(result[0].cpm).to.not.equal(null); expect(result[0].creativeId).to.not.equal(null); diff --git a/test/spec/modules/teqBlazeSalesAgentBidAdapter_spec.js b/test/spec/modules/teqBlazeSalesAgentBidAdapter_spec.js new file mode 100644 index 00000000000..f2dbe70f30d --- /dev/null +++ b/test/spec/modules/teqBlazeSalesAgentBidAdapter_spec.js @@ -0,0 +1,440 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/teqBlazeSalesAgentBidAdapter.js'; +import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'teqBlazeSalesAgent'; + +describe('TeqBlazeSalesAgentBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo', + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + + } + } + + const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, + refererInfo: { + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK', + }, + site: { + ext: { + data: { + scope3_aee: { + include: 'include', + exclude: 'exclude', + macro: 'macro' + } + } + } + } + }, + timeout: 500 + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and key parameters present', function () { + expect(spec.isBidRequestValid(bids[0])).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests(bids, bidderRequest); + + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + + it('Returns general data valid', function () { + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys( + 'deviceWidth', + 'deviceHeight', + 'device', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax', + 'bcat', + 'badv', + 'bapp', + 'battr' + ); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); + }); + + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + expect(placement.axei).to.exist.and.to.be.equal('include'); + expect(placement.axex).to.exist.and.to.be.equal('exclude'); + expect(placement.axem).to.exist.and.to.be.equal('macro'); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + }) + }); + + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + const dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + const dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + const dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + const serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + const serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); +}); diff --git a/test/spec/modules/theAdxBidAdapter_spec.js b/test/spec/modules/theAdxBidAdapter_spec.js index fd2a306ca05..2b531b6b10b 100644 --- a/test/spec/modules/theAdxBidAdapter_spec.js +++ b/test/spec/modules/theAdxBidAdapter_spec.js @@ -416,7 +416,7 @@ describe('TheAdxAdapter', function () { expect(result).to.eql([]); }); - it('returns a valid bid response on sucessful banner request', function () { + it('returns a valid bid response on successful banner request', function () { const incomingRequestId = 'XXtestingXX'; const responsePrice = 3.14 @@ -484,7 +484,7 @@ describe('TheAdxAdapter', function () { expect(processedBid.currency).to.equal(responseCurrency); }); - it('returns a valid deal bid response on sucessful banner request with deal', function () { + it('returns a valid deal bid response on successful banner request with deal', function () { const incomingRequestId = 'XXtestingXX'; const responsePrice = 3.14 @@ -556,7 +556,7 @@ describe('TheAdxAdapter', function () { expect(processedBid.dealId).to.equal(dealId); }); - it('returns an valid bid response on sucessful video request', function () { + it('returns an valid bid response on successful video request', function () { const incomingRequestId = 'XXtesting-275XX'; const responsePrice = 6 const vast_url = 'https://theadx.com/vast?rid=a8ae0b48-a8db-4220-ba0c-7458f452b1f5&{FOR_COVARAGE}' @@ -622,7 +622,7 @@ describe('TheAdxAdapter', function () { expect(processedBid.vastUrl).to.equal(vast_url); }); - it('returns an valid bid response on sucessful native request', function () { + it('returns an valid bid response on successful native request', function () { const incomingRequestId = 'XXtesting-275XX'; const responsePrice = 6 const nurl = 'https://app.theadx.com/ixc?rid=02aefd80-2df9-11e9-896d-d33384d77f5c&time=v-1549888312715&sp=1WzMjcRpeyk%3D'; diff --git a/test/spec/modules/timeoutRtdProvider_spec.js b/test/spec/modules/timeoutRtdProvider_spec.js index 4776c52440e..fd21f39b23e 100644 --- a/test/spec/modules/timeoutRtdProvider_spec.js +++ b/test/spec/modules/timeoutRtdProvider_spec.js @@ -101,7 +101,7 @@ describe('Timeout RTD submodule', () => { } }); - const reqBidsConfigObj = {adUnits: [1, 2, 3]} + const reqBidsConfigObj = { adUnits: [1, 2, 3] } const addedTimeout = 400; const rules = { numAdUnits: { @@ -122,7 +122,7 @@ describe('Timeout RTD submodule', () => { } }); - const reqBidsConfigObj = {adUnits: [1, 2, 3]} + const reqBidsConfigObj = { adUnits: [1, 2, 3] } const addedTimeout = 400; const rules = { numAdUnits: { diff --git a/test/spec/modules/tncIdSystem_spec.js b/test/spec/modules/tncIdSystem_spec.js index c681970c27d..301c971a917 100644 --- a/test/spec/modules/tncIdSystem_spec.js +++ b/test/spec/modules/tncIdSystem_spec.js @@ -32,18 +32,18 @@ describe('TNCID tests', function () { describe('getId', () => { afterEach(function () { - Object.defineProperty(window, '__tnc', {value: undefined, configurable: true}); - Object.defineProperty(window, '__tncPbjs', {value: undefined, configurable: true}); + Object.defineProperty(window, '__tnc', { value: undefined, configurable: true }); + Object.defineProperty(window, '__tncPbjs', { value: undefined, configurable: true }); }); it('Should NOT give TNCID if GDPR applies but consent string is missing', function () { - const res = tncidSubModule.getId({}, { gdpr: {gdprApplies: true} }); + const res = tncidSubModule.getId({}, { gdpr: { gdprApplies: true } }); expect(res).to.be.undefined; }); it('Should NOT give TNCID if there is no TNC script on page and no fallback url in configuration', async function () { const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({}, consentData); + const { callback } = tncidSubModule.getId({}, consentData); await callback(completeCallback); expect(callback).to.be.an('function'); @@ -52,7 +52,7 @@ describe('TNCID tests', function () { it('Should NOT give TNCID if fallback script is not loaded correctly', async function () { const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({ + const { callback } = tncidSubModule.getId({ params: { url: 'www.thenewco.tech' } }, consentData); @@ -62,7 +62,7 @@ describe('TNCID tests', function () { it(`Should call external script if TNC is not loaded on page`, async function() { const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({params: {url: 'https://www.thenewco.tech?providerId=test'}}, { gdprApplies: false }); + const { callback } = tncidSubModule.getId({ params: { url: 'https://www.thenewco.tech?providerId=test' } }, { gdprApplies: false }); await callback(completeCallback); expect(window).to.contain.property('__tncPbjs'); @@ -78,7 +78,7 @@ describe('TNCID tests', function () { }); const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({}, { gdprApplies: false }); + const { callback } = tncidSubModule.getId({}, { gdprApplies: false }); await callback(completeCallback); expect(completeCallback.calledOnceWithExactly('TNCID_TEST_ID_1')).to.be.true; @@ -86,7 +86,7 @@ describe('TNCID tests', function () { it('TNC script with ns __tncPbjs is created', async function () { const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({params: {url: 'TEST_URL'}}, consentData); + const { callback } = tncidSubModule.getId({ params: { url: 'TEST_URL' } }, consentData); await callback(completeCallback); expect(window).to.contain.property('__tncPbjs'); @@ -104,7 +104,7 @@ describe('TNCID tests', function () { }); const completeCallback = sinon.spy(); - const {callback} = tncidSubModule.getId({params: {url: 'www.thenewco.tech'}}, consentData); + const { callback } = tncidSubModule.getId({ params: { url: 'www.thenewco.tech' } }, consentData); await callback(completeCallback); expect(completeCallback.calledOnceWithExactly('TNCID_TEST_ID_2')).to.be.true; diff --git a/test/spec/modules/topLevelPaapi_spec.js b/test/spec/modules/topLevelPaapi_spec.js index c08a14f899f..f20a2aa25aa 100644 --- a/test/spec/modules/topLevelPaapi_spec.js +++ b/test/spec/modules/topLevelPaapi_spec.js @@ -4,8 +4,8 @@ import { registerSubmodule, reset as resetPaapi } from '../../../modules/paapi.js'; -import {config} from 'src/config.js'; -import {BID_STATUS, EVENTS} from 'src/constants.js'; +import { config } from 'src/config.js'; +import { BID_STATUS, EVENTS } from 'src/constants.js'; import * as events from 'src/events.js'; import { getPaapiAdId, @@ -15,9 +15,9 @@ import { parsePaapiSize, resizeCreativeHook, topLevelPAAPI } from '../../../modules/topLevelPaapi.js'; -import {auctionManager} from '../../../src/auctionManager.js'; -import {expect} from 'chai/index.js'; -import {getBidToRender} from '../../../src/adRendering.js'; +import { auctionManager } from '../../../src/auctionManager.js'; +import { expect } from 'chai/index.js'; +import { getBidToRender } from '../../../src/adRendering.js'; describe('topLevelPaapi', () => { let sandbox, auctionConfig, next, auctionId, auctions; @@ -33,7 +33,7 @@ describe('topLevelPaapi', () => { beforeEach(() => { sandbox = sinon.createSandbox(); auctions = {}; - sandbox.stub(auctionManager.index, 'getAuction').callsFake(({auctionId}) => auctions[auctionId]?.auction); + sandbox.stub(auctionManager.index, 'getAuction').callsFake(({ auctionId }) => auctions[auctionId]?.auction); next = sinon.stub(); auctionId = 'auct'; auctionConfig = { @@ -74,7 +74,7 @@ describe('topLevelPaapi', () => { } }; } - addPaapiConfigHook(next, {adUnitCode, auctionId: _auctionId}, { + addPaapiConfigHook(next, { adUnitCode, auctionId: _auctionId }, { config: { ...auctionConfig, auctionId: _auctionId, @@ -84,8 +84,8 @@ describe('topLevelPaapi', () => { } function endAuctions() { - Object.entries(auctions).forEach(([auctionId, {adUnits}]) => { - events.emit(EVENTS.AUCTION_END, {auctionId, adUnitCodes: Object.keys(adUnits), adUnits: Object.values(adUnits)}); + Object.entries(auctions).forEach(([auctionId, { adUnits }]) => { + events.emit(EVENTS.AUCTION_END, { auctionId, adUnitCodes: Object.keys(adUnits), adUnits: Object.values(adUnits) }); }); } @@ -155,20 +155,20 @@ describe('topLevelPaapi', () => { Object.entries({ 'a string URN': { pack: (val) => val, - unpack: (urn) => ({urn}), + unpack: (urn) => ({ urn }), canRender: true, }, 'a frameConfig object': { - pack: (val) => ({val}), - unpack: (val) => ({frameConfig: {val}}), + pack: (val) => ({ val }), + unpack: (val) => ({ frameConfig: { val } }), canRender: false } - }).forEach(([t, {pack, unpack, canRender}]) => { + }).forEach(([t, { pack, unpack, canRender }]) => { describe(`when runAdAuction returns ${t}`, () => { let raa; beforeEach(() => { raa = sinon.stub().callsFake((cfg) => { - const {auctionId, adUnitCode} = cfg.componentAuctions[0]; + const { auctionId, adUnitCode } = cfg.componentAuctions[0]; return Promise.resolve(pack(`raa-${adUnitCode}-${auctionId}`)); }); }); @@ -196,7 +196,7 @@ describe('topLevelPaapi', () => { endAuctions(); }); it('should resolve to raa result', () => { - return getBids({adUnitCode: 'au', auctionId}).then(result => { + return getBids({ adUnitCode: 'au', auctionId }).then(result => { sinon.assert.calledOnce(raa); sinon.assert.calledWith( raa, @@ -211,7 +211,7 @@ describe('topLevelPaapi', () => { ]) }) ); - expectBids(result, {au: 'raa-au-auct'}); + expectBids(result, { au: 'raa-au-auct' }); }); }); @@ -222,17 +222,17 @@ describe('topLevelPaapi', () => { }).forEach(([t, behavior]) => { it('should resolve to null when runAdAuction returns null', () => { raa = sinon.stub().callsFake(behavior); - return getBids({adUnitCode: 'au', auctionId: 'auct'}).then(result => { - expectBids(result, {au: null}); + return getBids({ adUnitCode: 'au', auctionId: 'auct' }).then(result => { + expectBids(result, { au: null }); }); }); }) it('should resolve to the same result when called again', () => { - getBids({adUnitCode: 'au', auctionId}); - return getBids({adUnitCode: 'au', auctionId: 'auct'}).then(result => { + getBids({ adUnitCode: 'au', auctionId }); + return getBids({ adUnitCode: 'au', auctionId: 'auct' }).then(result => { sinon.assert.calledOnce(raa); - expectBids(result, {au: 'raa-au-auct'}); + expectBids(result, { au: 'raa-au-auct' }); }); }); @@ -242,8 +242,8 @@ describe('topLevelPaapi', () => { }); it('should fire PAAPI_RUN_AUCTION', () => { return Promise.all([ - getBids({adUnitCode: 'au', auctionId}), - getBids({adUnitCode: 'other', auctionId}) + getBids({ adUnitCode: 'au', auctionId }), + getBids({ adUnitCode: 'other', auctionId }) ]).then(() => { sinon.assert.calledWith(events.emit, EVENTS.RUN_PAAPI_AUCTION, { adUnitCode: 'au', @@ -256,7 +256,7 @@ describe('topLevelPaapi', () => { }); }); it('should fire PAAPI_BID', () => { - return getBids({adUnitCode: 'au', auctionId}).then(() => { + return getBids({ adUnitCode: 'au', auctionId }).then(() => { sinon.assert.calledWith(events.emit, EVENTS.PAAPI_BID, sinon.match({ ...unpack('raa-au-auct'), adUnitCode: 'au', @@ -266,7 +266,7 @@ describe('topLevelPaapi', () => { }); it('should fire PAAPI_NO_BID', () => { raa = sinon.stub().callsFake(() => Promise.resolve(null)); - return getBids({adUnitCode: 'au', auctionId}).then(() => { + return getBids({ adUnitCode: 'au', auctionId }).then(() => { sinon.assert.calledWith(events.emit, EVENTS.PAAPI_NO_BID, sinon.match({ adUnitCode: 'au', auctionId: 'auct' @@ -276,12 +276,12 @@ describe('topLevelPaapi', () => { it('should fire PAAPI_ERROR', () => { raa = sinon.stub().callsFake(() => Promise.reject(new Error('message'))); - return getBids({adUnitCode: 'au', auctionId}).then(res => { - expect(res).to.eql({au: null}); + return getBids({ adUnitCode: 'au', auctionId }).then(res => { + expect(res).to.eql({ au: null }); sinon.assert.calledWith(events.emit, EVENTS.PAAPI_ERROR, sinon.match({ adUnitCode: 'au', auctionId: 'auct', - error: sinon.match({message: 'message'}) + error: sinon.match({ message: 'message' }) })); }); }); @@ -292,7 +292,7 @@ describe('topLevelPaapi', () => { } it('should hook into getBidToRender', () => { - return getBids({adUnitCode: 'au', auctionId}).then(res => { + return getBids({ adUnitCode: 'au', auctionId }).then(res => { return getBidToRenderPm(res.au.adId).then(bidToRender => [res.au, bidToRender]) }).then(([paapiBid, bidToRender]) => { if (canRender) { @@ -322,7 +322,7 @@ describe('topLevelPaapi', () => { it(`should ${!canRender ? 'NOT' : ''} override winning bid for the same adUnit`, () => { return Promise.all([ - getBids({adUnitCode: 'au', auctionId}).then(res => res.au), + getBids({ adUnitCode: 'au', auctionId }).then(res => res.au), getBidToRenderPm(mockContextual.adId) ]).then(([paapiBid, bidToRender]) => { if (canRender) { @@ -342,7 +342,7 @@ describe('topLevelPaapi', () => { }); it('should not override when already a paapi bid', () => { - return getBids({adUnitCode: 'au', auctionId}).then(res => { + return getBids({ adUnitCode: 'au', auctionId }).then(res => { return getBidToRenderPm(res.au.adId).then((bidToRender) => [bidToRender, res.au]); }).then(([bidToRender, paapiBid]) => { expect(bidToRender).to.eql(canRender ? paapiBid : mockContextual) @@ -388,7 +388,7 @@ describe('topLevelPaapi', () => { return Promise.all( [ [ - {adUnitCode: 'au1', auctionId: 'auct1'}, + { adUnitCode: 'au1', auctionId: 'auct1' }, { au1: 'raa-au1-auct1' } @@ -402,14 +402,14 @@ describe('topLevelPaapi', () => { } ], [ - {auctionId: 'auct1'}, + { auctionId: 'auct1' }, { au1: 'raa-au1-auct1', au2: 'raa-au2-auct1' } ], [ - {adUnitCode: 'au1'}, + { adUnitCode: 'au1' }, { au1: 'raa-au1-auct2' } @@ -489,8 +489,8 @@ describe('topLevelPaapi', () => { }); }); it('does not touch non-paapi bids', () => { - getRenderingDataHook(next, {bid: 'data'}, {other: 'options'}); - sinon.assert.calledWith(next, {bid: 'data'}, {other: 'options'}); + getRenderingDataHook(next, { bid: 'data' }, { other: 'options' }); + sinon.assert.calledWith(next, { bid: 'data' }, { other: 'options' }); }); }); @@ -499,15 +499,15 @@ describe('topLevelPaapi', () => { sandbox.stub(events, 'emit'); }); it('handles paapi bids', () => { - const bid = {source: 'paapi'}; + const bid = { source: 'paapi' }; markWinningBidHook(next, bid); sinon.assert.notCalled(next); sinon.assert.called(next.bail); sinon.assert.calledWith(events.emit, EVENTS.BID_WON, bid); }); it('ignores non-paapi bids', () => { - markWinningBidHook(next, {other: 'bid'}); - sinon.assert.calledWith(next, {other: 'bid'}); + markWinningBidHook(next, { other: 'bid' }); + sinon.assert.calledWith(next, { other: 'bid' }); sinon.assert.notCalled(next.bail); }); }); diff --git a/test/spec/modules/topicsFpdModule_spec.js b/test/spec/modules/topicsFpdModule_spec.js index 47838ecdde1..1d8fbbad445 100644 --- a/test/spec/modules/topicsFpdModule_spec.js +++ b/test/spec/modules/topicsFpdModule_spec.js @@ -8,12 +8,12 @@ import { reset, topicStorageName } from '../../../modules/topicsFpdModule.js'; -import {config} from 'src/config.js'; -import {deepClone, safeJSONParse} from '../../../src/utils.js'; -import {getCoreStorageManager} from 'src/storageManager.js'; +import { config } from 'src/config.js'; +import { deepClone, safeJSONParse } from '../../../src/utils.js'; +import { getCoreStorageManager } from 'src/storageManager.js'; import * as activities from '../../../src/activities/rules.js'; -import {registerActivityControl} from '../../../src/activities/rules.js'; -import {ACTIVITY_ENRICH_UFPD} from '../../../src/activities/activities.js'; +import { registerActivityControl } from '../../../src/activities/rules.js'; +import { ACTIVITY_ENRICH_UFPD } from '../../../src/activities/activities.js'; describe('topics', () => { let unregister, enrichUfpdRule; @@ -25,7 +25,7 @@ describe('topics', () => { }); beforeEach(() => { - enrichUfpdRule = () => ({allow: true}); + enrichUfpdRule = () => ({ allow: true }); reset(); }); @@ -61,7 +61,7 @@ describe('topics', () => { segclass: 'm1' }, segment: [ - {id: '123'} + { id: '123' } ] } ] @@ -76,8 +76,8 @@ describe('topics', () => { segclass: 'm1' }, segment: [ - {id: '123'}, - {id: '321'} + { id: '123' }, + { id: '321' } ] } ] @@ -92,8 +92,8 @@ describe('topics', () => { segclass: 'm1' }, segment: [ - {id: '1'}, - {id: '2'} + { id: '1' }, + { id: '2' } ] }, { @@ -102,7 +102,7 @@ describe('topics', () => { segclass: 'm2' }, segment: [ - {id: '3'} + { id: '3' } ] } ] @@ -117,7 +117,7 @@ describe('topics', () => { segclass: 'm1' }, segment: [ - {id: '123'} + { id: '123' } ] } ] @@ -140,7 +140,7 @@ describe('topics', () => { segclass: 'm1' }, segment: [ - {id: '123'} + { id: '123' } ] }, { @@ -149,7 +149,7 @@ describe('topics', () => { segclass: 'm1', }, segment: [ - {id: '321'} + { id: '321' } ] }, { @@ -158,12 +158,12 @@ describe('topics', () => { segclass: 'm2' }, segment: [ - {id: '213'} + { id: '213' } ] } ] } - ].forEach(({t, topics, expected, taxonomies}) => { + ].forEach(({ t, topics, expected, taxonomies }) => { describe(`on ${t}`, () => { it('should convert topics to user.data segments correctly', () => { const actual = getTopicsData('mockName', topics, taxonomies); @@ -231,17 +231,17 @@ describe('topics', () => { const mockData = [ { name: 'domain', - segment: [{id: 123}] + segment: [{ id: 123 }] }, { name: 'domain', - segment: [{id: 321}] + segment: [{ id: 321 }] } ]; it('should add topics data', () => { - return processFpd({}, {global: {}}, {data: Promise.resolve(mockData)}) - .then(({global}) => { + return processFpd({}, { global: {} }, { data: Promise.resolve(mockData) }) + .then(({ global }) => { expect(global.user.data).to.eql(mockData); }); }); @@ -250,18 +250,18 @@ describe('topics', () => { const global = { user: { data: [ - {name: 'preexisting'}, + { name: 'preexisting' }, ] } }; - return processFpd({}, {global: deepClone(global)}, {data: Promise.resolve(mockData)}) + return processFpd({}, { global: deepClone(global) }, { data: Promise.resolve(mockData) }) .then((data) => { expect(data.global.user.data).to.eql(global.user.data.concat(mockData)); }); }); it('should not modify fpd when there is no data', () => { - return processFpd({}, {global: {}}, {data: Promise.resolve([])}) + return processFpd({}, { global: {} }, { data: Promise.resolve([]) }) .then((data) => { expect(data.global).to.eql({}); }); @@ -304,9 +304,9 @@ describe('topics', () => { }); it('does not load frames when accessDevice is not allowed', () => { - enrichUfpdRule = ({component}) => { + enrichUfpdRule = ({ component }) => { if (component === 'bidder.mockBidder') { - return {allow: false} + return { allow: false } } } const doc = { @@ -358,7 +358,7 @@ describe('topics', () => { }); it('should return no segments when not configured', () => { - config.setConfig({userSync: {}}); + config.setConfig({ userSync: {} }); expect(getCachedTopics()).to.eql([]); }) @@ -367,8 +367,8 @@ describe('topics', () => { const storedSegments = JSON.stringify( [['pubmatic', { '2206021246': { - 'ext': {'segtax': 600, 'segclass': '2206021246'}, - 'segment': [{'id': '243'}, {'id': '265'}], + 'ext': { 'segtax': 600, 'segclass': '2206021246' }, + 'segment': [{ 'id': '243' }, { 'id': '265' }], 'name': 'ads.pubmatic.com' }, 'lastUpdated': new Date().getTime() @@ -393,7 +393,7 @@ describe('topics', () => { }); it('should NOT return segments for bidder if enrichUfpd is NOT allowed', () => { - enrichUfpdRule = (params) => ({allow: params.component !== 'bidder.pubmatic'}) + enrichUfpdRule = (params) => ({ allow: params.component !== 'bidder.pubmatic' }) expect(getCachedTopics()).to.eql([]); }); }); @@ -429,7 +429,7 @@ describe('topics', () => { featurePolicy: { allowsFeature() { return true } }, - createElement: sinon.stub().callsFake(() => ({style: {}})), + createElement: sinon.stub().callsFake(() => ({ style: {} })), documentElement: { appendChild() {} } @@ -524,8 +524,8 @@ describe('topics', () => { const storedSegments = JSON.stringify( [['pubmatic', { '2206021246': { - 'ext': {'segtax': 600, 'segclass': '2206021246'}, - 'segment': [{'id': '243'}, {'id': '265'}], + 'ext': { 'segtax': 600, 'segclass': '2206021246' }, + 'segment': [{ 'id': '243' }, { 'id': '265' }], 'name': 'ads.pubmatic.com' }, 'lastUpdated': new Date().getTime() diff --git a/test/spec/modules/tpmnBidAdapter_spec.js b/test/spec/modules/tpmnBidAdapter_spec.js index e099d9d5911..46cc6513343 100644 --- a/test/spec/modules/tpmnBidAdapter_spec.js +++ b/test/spec/modules/tpmnBidAdapter_spec.js @@ -1,11 +1,11 @@ -import {spec, storage, VIDEO_RENDERER_URL} from 'modules/tpmnBidAdapter.js'; -import {generateUUID} from '../../../src/utils.js'; -import {expect} from 'chai'; +import { spec, storage, VIDEO_RENDERER_URL } from 'modules/tpmnBidAdapter.js'; +import { generateUUID } from '../../../src/utils.js'; +import { expect } from 'chai'; import * as utils from 'src/utils'; import * as sinon from 'sinon'; import 'modules/consentManagementTcf.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const BIDDER_CODE = 'tpmn'; const BANNER_BID = { @@ -262,7 +262,7 @@ describe('tpmnAdapterTests', function () { expect(spec.isBidRequestValid(bid)).to.equal(true); const requests = spec.buildRequests([bid], BIDDER_REQUEST); const request = requests[0].data; - expect(request.imp[0].video).to.deep.include({...check}); + expect(request.imp[0].video).to.deep.include({ ...check }); }); } @@ -270,8 +270,8 @@ describe('tpmnAdapterTests', function () { it('when mediaType New Video', () => { const NEW_VIDEO_BID = { 'bidder': 'tpmn', - 'params': {'inventoryId': 2, 'bidFloor': 2}, - 'userId': {'pubcid': '88a49ee6-beeb-4dd6-92ac-3b6060e127e1'}, + 'params': { 'inventoryId': 2, 'bidFloor': 2 }, + 'userId': { 'pubcid': '88a49ee6-beeb-4dd6-92ac-3b6060e127e1' }, 'mediaTypes': { 'video': { 'context': 'outstream', @@ -293,7 +293,7 @@ describe('tpmnAdapterTests', function () { const check = { w: 1024, h: 768, - mimes: [ 'video/mp4' ], + mimes: ['video/mp4'], playbackmethod: [2, 4, 6], api: [1, 2, 3, 6], protocols: [3, 4], @@ -340,14 +340,14 @@ describe('tpmnAdapterTests', function () { h: 480 }; - bid.mediaTypes.video = {...check}; + bid.mediaTypes.video = { ...check }; bid.mediaTypes.video.context = 'instream'; bid.mediaTypes.video.playerSize = [[640, 480]]; expect(spec.isBidRequestValid(bid)).to.equal(true); const requests = spec.buildRequests([bid], BIDDER_REQUEST); const request = requests[0].data; - expect(request.imp[0].video).to.deep.include({...check}); + expect(request.imp[0].video).to.deep.include({ ...check }); }); } }); @@ -430,7 +430,7 @@ describe('tpmnAdapterTests', function () { }); it('case 1 -> allow iframe', () => { - const syncs = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }); expect(syncs.length).to.equal(1); expect(syncs[0].type).to.equal('iframe'); }); diff --git a/test/spec/modules/trafficgateBidAdapter_spec.js b/test/spec/modules/trafficgateBidAdapter_spec.js index 27550b2cd20..1b560937c99 100644 --- a/test/spec/modules/trafficgateBidAdapter_spec.js +++ b/test/spec/modules/trafficgateBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/trafficgateBidAdapter'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {BANNER, VIDEO} from 'src/mediaTypes.js'; -import {config} from 'src/config.js'; +import { expect } from 'chai'; +import { spec } from 'modules/trafficgateBidAdapter'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import * as dnt from 'libraries/dnt/index.js'; import 'src/prebid.js' @@ -14,9 +14,9 @@ import 'modules/consentManagementTcf.js'; import 'modules/consentManagementUsp.js'; import 'modules/paapi.js'; -import {deepClone} from 'src/utils.js'; -import {addFPDToBidderRequest} from '../../helpers/fpd.js'; -import {hook} from '../../../src/hook.js'; +import { deepClone } from 'src/utils.js'; +import { addFPDToBidderRequest } from '../../helpers/fpd.js'; +import { hook } from '../../../src/hook.js'; const BidRequestBuilder = function BidRequestBuilder(options) { const defaults = { @@ -90,7 +90,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { bidder: 'trafficgate', params: {}, adUnitCode: 'adunit-code', - mediaTypes: {banner: {}}, + mediaTypes: { banner: {} }, sizes: [[300, 250], [300, 600]], bidId: '30b31c1838de1e', bidderRequestId: '22edbae2733bf6', @@ -99,13 +99,13 @@ describe('TrafficgateOpenxRtbAdapter', function () { }); it('should return false when there is placementId only', function () { - bannerBid.params = {'placementId': '98765'}; + bannerBid.params = { 'placementId': '98765' }; expect(spec.isBidRequestValid(bannerBid)).to.equal(false); }); describe('should return false when there is a host only', function () { beforeEach(function () { - bannerBid.params = {host: 'test-delivery-domain'} + bannerBid.params = { host: 'test-delivery-domain' } }); it('should return false when there is no placementId and size', function () { @@ -267,7 +267,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { let mockBidderRequest; beforeEach(function () { - mockBidderRequest = {refererInfo: {}}; + mockBidderRequest = { refererInfo: {} }; bidRequestsWithMediaTypes = [{ bidder: 'trafficgate', @@ -412,7 +412,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { describe('FPD', function() { let bidRequests; - const mockBidderRequest = {refererInfo: {}}; + const mockBidderRequest = { refererInfo: {} }; beforeEach(function () { bidRequests = [{ @@ -629,27 +629,28 @@ describe('TrafficgateOpenxRtbAdapter', function () { describe('with user agent client hints', function () { it('should add device.sua if available', function () { - const bidderRequestWithUserAgentClientHints = { refererInfo: {}, + const bidderRequestWithUserAgentClientHints = { + refererInfo: {}, ortb2: { device: { sua: { source: 2, platform: { brand: 'macOS', - version: [ '12', '4', '0' ] + version: ['12', '4', '0'] }, browsers: [ { brand: 'Chromium', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Google Chrome', - version: [ '106', '0', '5249', '119' ] + version: ['106', '0', '5249', '119'] }, { brand: 'Not;A=Brand', - version: [ '99', '0', '0', '0' ] + version: ['99', '0', '0', '0'] }], mobile: 0, model: 'Pro', @@ -657,12 +658,13 @@ describe('TrafficgateOpenxRtbAdapter', function () { architecture: 'x86' } } - }}; + } + }; let request = spec.buildRequests(bidRequests, bidderRequestWithUserAgentClientHints); expect(request[0].data.device.sua).to.exist; expect(request[0].data.device.sua).to.deep.equal(bidderRequestWithUserAgentClientHints.ortb2.device.sua); - const bidderRequestWithoutUserAgentClientHints = {refererInfo: {}, ortb2: {}}; + const bidderRequestWithoutUserAgentClientHints = { refererInfo: {}, ortb2: {} }; request = spec.buildRequests(bidRequests, bidderRequestWithoutUserAgentClientHints); expect(request[0].data.device?.sua).to.not.exist; }); @@ -838,7 +840,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { it('should send a coppa flag there is when there is coppa param settings in the bid params', async function () { const request = spec.buildRequests(bidRequestsWithMediaTypes, await addFPDToBidderRequest(mockBidderRequest)); - request.params = {coppa: true}; + request.params = { coppa: true }; expect(request[0].data.regs.coppa).to.equal(1); }); @@ -932,15 +934,17 @@ describe('TrafficgateOpenxRtbAdapter', function () { bidId: 'test-bid-id-1', bidderRequestId: 'test-bid-request-1', auctionId: 'test-auction-1', - ortb2: {source: { - ext: {schain: schainConfig} - }} + ortb2: { + source: { + ext: { schain: schainConfig } + } + } }]; // Add schain to mockBidderRequest as well mockBidderRequest.ortb2 = { source: { - ext: {schain: schainConfig} + ext: { schain: schainConfig } } }; }); @@ -1012,7 +1016,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-1', }]; // enrich bid request with userId key/value - mockBidderRequest.ortb2 = {user: {ext: {eids: userIdAsEids}}} + mockBidderRequest.ortb2 = { user: { ext: { eids: userIdAsEids } } } const request = spec.buildRequests(bidRequestsWithUserId, mockBidderRequest); expect(request[0].data.user.ext.eids).to.eql(userIdAsEids); }); @@ -1118,10 +1122,10 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; - bidResponse = {nbr: 0}; // Unknown error - bids = spec.interpretResponse({body: bidResponse}, bidRequest); + bidResponse = { nbr: 0 }; // Unknown error + bids = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1149,10 +1153,10 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; - bidResponse = {ext: {}, id: 'test-bid-id'}; - bids = spec.interpretResponse({body: bidResponse}, bidRequest); + bidResponse = { ext: {}, id: 'test-bid-id' }; + bids = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1180,10 +1184,10 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = ''; // Unknown error - bids = spec.interpretResponse({body: bidResponse}, bidRequest); + bids = spec.interpretResponse({ body: bidResponse }, bidRequest); }); it('should not return any bids', function () { @@ -1231,10 +1235,10 @@ describe('TrafficgateOpenxRtbAdapter', function () { context('when there is a response, the common response properties', function () { beforeEach(function () { bidRequestConfigs = deepClone(SAMPLE_BID_REQUESTS); - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = deepClone(SAMPLE_BID_RESPONSE); - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest)[0]; }); it('should return a price', function () { @@ -1302,7 +1306,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1319,7 +1323,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { cur: 'AUS' }; - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest)[0]; }); it('should return the proper mediaType', function () { @@ -1349,7 +1353,7 @@ describe('TrafficgateOpenxRtbAdapter', function () { auctionId: 'test-auction-id' }]; - bidRequest = spec.buildRequests(bidRequestConfigs, {refererInfo: {}})[0]; + bidRequest = spec.buildRequests(bidRequestConfigs, { refererInfo: {} })[0]; bidResponse = { seatbid: [{ @@ -1368,14 +1372,14 @@ describe('TrafficgateOpenxRtbAdapter', function () { }); it('should return the proper mediaType', function () { - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest)[0]; expect(bid.mediaType).to.equal(Object.keys(bidRequestConfigs[0].mediaTypes)[0]); }); it('should return the proper mediaType', function () { const winUrl = 'https//my.win.url'; bidResponse.seatbid[0].bid[0].nurl = winUrl - bid = spec.interpretResponse({body: bidResponse}, bidRequest)[0]; + bid = spec.interpretResponse({ body: bidResponse }, bidRequest)[0]; expect(bid.vastUrl).to.equal(winUrl); }); diff --git a/test/spec/modules/trionBidAdapter_spec.js b/test/spec/modules/trionBidAdapter_spec.js index 306cacc2487..713447d1bd6 100644 --- a/test/spec/modules/trionBidAdapter_spec.js +++ b/test/spec/modules/trionBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import * as utils from 'src/utils.js'; -import {spec, acceptPostMessage, getStorageData, setStorageData} from 'modules/trionBidAdapter.js'; -import {deepClone} from 'src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { spec, acceptPostMessage, getStorageData, setStorageData } from 'modules/trionBidAdapter.js'; +import { deepClone } from 'src/utils.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const CONSTANTS = require('src/constants.js'); const adloader = require('src/adloader'); @@ -278,13 +278,13 @@ describe('Trion adapter tests', function () { describe('interpretResponse', function () { it('when there is no response do not bid', function () { - const response = spec.interpretResponse(null, {bidRequest: TRION_BID}); + const response = spec.interpretResponse(null, { bidRequest: TRION_BID }); expect(response).to.deep.equal([]); }); it('when place bid is returned as false', function () { TRION_BID_RESPONSE.result.placeBid = false; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(response).to.deep.equal([]); @@ -293,14 +293,14 @@ describe('Trion adapter tests', function () { it('when no cpm is in the response', function () { TRION_BID_RESPONSE.result.cpm = 0; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.cpm = 1; }); it('when no ad is in the response', function () { TRION_BID_RESPONSE.result.ad = null; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(response).to.deep.equal([]); TRION_BID_RESPONSE.result.ad = 'test'; }); @@ -310,7 +310,7 @@ describe('Trion adapter tests', function () { const bidHeight = '2'; TRION_BID_RESPONSE.result.width = bidWidth; TRION_BID_RESPONSE.result.height = bidHeight; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(response[0].width).to.equal(bidWidth); expect(response[0].height).to.equal(bidHeight); TRION_BID_RESPONSE.result.width = '300'; @@ -320,14 +320,14 @@ describe('Trion adapter tests', function () { it('cpm is properly set and transformed to cents', function () { const bidCpm = 2; TRION_BID_RESPONSE.result.cpm = bidCpm * 100; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(response[0].cpm).to.equal(bidCpm); TRION_BID_RESPONSE.result.cpm = 100; }); it('advertiserDomains is included when sent by server', function () { TRION_BID_RESPONSE.result.adomain = ['test_adomain']; - const response = spec.interpretResponse({body: TRION_BID_RESPONSE}, {bidRequest: TRION_BID}); + const response = spec.interpretResponse({ body: TRION_BID_RESPONSE }, { bidRequest: TRION_BID }); expect(Object.keys(response[0].meta)).to.include.members(['advertiserDomains']); expect(response[0].meta.advertiserDomains).to.deep.equal(['test_adomain']); delete TRION_BID_RESPONSE.result.adomain; @@ -352,12 +352,12 @@ describe('Trion adapter tests', function () { }); it('should register trion user script', function () { - const syncs = spec.getUserSyncs({iframeEnabled: true}); + const syncs = spec.getUserSyncs({ iframeEnabled: true }); const pageUrl = getPublisherUrl(); const pubId = 1; const sectionId = 2; const syncString = `?p=${pubId}&s=${sectionId}&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); + expect(syncs[0]).to.deep.equal({ type: 'iframe', url: USER_SYNC_URL + syncString }); }); it('should register trion user script with gdpr params', function () { @@ -365,31 +365,31 @@ describe('Trion adapter tests', function () { consentString: 'test_gdpr_str', gdprApplies: true }; - const syncs = spec.getUserSyncs({iframeEnabled: true}, null, gdprConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, null, gdprConsent); const pageUrl = getPublisherUrl(); const pubId = 1; const sectionId = 2; const gcEncoded = encodeURIComponent(gdprConsent.consentString); const syncString = `?p=${pubId}&s=${sectionId}&gc=${gcEncoded}&g=1&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); + expect(syncs[0]).to.deep.equal({ type: 'iframe', url: USER_SYNC_URL + syncString }); }); it('should register trion user script with us privacy params', function () { const uspConsent = '1YYY'; - const syncs = spec.getUserSyncs({iframeEnabled: true}, null, null, uspConsent); + const syncs = spec.getUserSyncs({ iframeEnabled: true }, null, null, uspConsent); const pageUrl = getPublisherUrl(); const pubId = 1; const sectionId = 2; const uspEncoded = encodeURIComponent(uspConsent); const syncString = `?p=${pubId}&s=${sectionId}&up=${uspEncoded}&u=${pageUrl}`; - expect(syncs[0]).to.deep.equal({type: 'iframe', url: USER_SYNC_URL + syncString}); + expect(syncs[0]).to.deep.equal({ type: 'iframe', url: USER_SYNC_URL + syncString }); }); it('should except posted messages from user sync script', function () { const testId = 'testId'; const message = BASE_KEY + 'userId=' + testId; setStorageData(BASE_KEY + 'int_t', null); - acceptPostMessage({data: message}); + acceptPostMessage({ data: message }); const newKey = getStorageData(BASE_KEY + 'int_t'); expect(newKey).to.equal(testId); }); @@ -399,7 +399,7 @@ describe('Trion adapter tests', function () { const badId = 'badId'; const message = 'Not Trion: userId=' + testId; setStorageData(BASE_KEY + 'int_t', badId); - acceptPostMessage({data: message}); + acceptPostMessage({ data: message }); const newKey = getStorageData(BASE_KEY + 'int_t'); expect(newKey).to.equal(badId); }); diff --git a/test/spec/modules/tripleliftBidAdapter_spec.js b/test/spec/modules/tripleliftBidAdapter_spec.js index 19c537e4da3..8b52932ae3e 100644 --- a/test/spec/modules/tripleliftBidAdapter_spec.js +++ b/test/spec/modules/tripleliftBidAdapter_spec.js @@ -5,7 +5,7 @@ import { deepClone } from 'src/utils.js'; import { config } from 'src/config.js'; import prebid from 'package.json'; import * as utils from 'src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const ENDPOINT = 'https://tlx.3lift.com/header/auction?'; const GDPR_CONSENT_STR = 'BOONm0NOONm0NABABAENAa-AAAARh7______b9_3__7_9uz_Kv_K7Vf7nnG072lPVA9LTOQ6gEaY'; @@ -645,7 +645,7 @@ describe('triplelift adapter', function () { it('should only parse sizes that are of the proper length and format', function () { const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); expect(request.data.imp[0].banner.format).to.have.length(2); - expect(request.data.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(request.data.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); }); it('should be a post request and populate the payload', function () { @@ -654,7 +654,7 @@ describe('triplelift adapter', function () { expect(payload).to.exist; expect(payload.imp[0].tagid).to.equal('12345'); expect(payload.imp[0].floor).to.equal(1.0); - expect(payload.imp[0].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(payload.imp[0].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); // instream expect(payload.imp[1].tagid).to.equal('insteam_test'); expect(payload.imp[1].floor).to.equal(1.0); @@ -663,16 +663,16 @@ describe('triplelift adapter', function () { // banner and outstream video expect(payload.imp[2]).to.have.property('video'); expect(payload.imp[2]).to.have.property('banner'); - expect(payload.imp[2].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); - expect(payload.imp[2].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream'}); + expect(payload.imp[2].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); + expect(payload.imp[2].video).to.deep.equal({ 'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream' }); // banner and incomplete video expect(payload.imp[3]).to.not.have.property('video'); expect(payload.imp[3]).to.have.property('banner'); - expect(payload.imp[3].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(payload.imp[3].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); // incomplete mediatypes.banner and incomplete video expect(payload.imp[4]).to.not.have.property('video'); expect(payload.imp[4]).to.have.property('banner'); - expect(payload.imp[4].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); + expect(payload.imp[4].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); // banner and instream video expect(payload.imp[5]).to.not.have.property('banner'); expect(payload.imp[5]).to.have.property('video'); @@ -681,20 +681,20 @@ describe('triplelift adapter', function () { // banner and outream video and native expect(payload.imp[6]).to.have.property('video'); expect(payload.imp[6]).to.have.property('banner'); - expect(payload.imp[6].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); - expect(payload.imp[6].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream'}); + expect(payload.imp[6].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); + expect(payload.imp[6].video).to.deep.equal({ 'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream' }); // outstream video only expect(payload.imp[7]).to.have.property('video'); expect(payload.imp[7]).to.not.have.property('banner'); - expect(payload.imp[7].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream'}); + expect(payload.imp[7].video).to.deep.equal({ 'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream' }); // banner and incomplete outstream (missing size); video request is permitted so banner can still monetize expect(payload.imp[8]).to.have.property('video'); expect(payload.imp[8]).to.have.property('banner'); - expect(payload.imp[8].banner.format).to.deep.equal([{w: 300, h: 250}, {w: 300, h: 600}]); - expect(payload.imp[8].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'context': 'outstream'}); + expect(payload.imp[8].banner.format).to.deep.equal([{ w: 300, h: 250 }, { w: 300, h: 600 }]); + expect(payload.imp[8].video).to.deep.equal({ 'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'context': 'outstream' }); // outstream new plcmt value expect(payload.imp[13]).to.have.property('video'); - expect(payload.imp[13].video).to.deep.equal({'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream', 'plcmt': 3}); + expect(payload.imp[13].video).to.deep.equal({ 'mimes': ['video/mp4'], 'maxduration': 30, 'minduration': 6, 'w': 640, 'h': 480, 'context': 'outstream', 'plcmt': 3 }); }); it('should check for valid outstream placement values', function () { @@ -779,7 +779,7 @@ describe('triplelift adapter', function () { const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const payload = request.data; expect(payload).to.exist; - expect(payload.user).to.deep.equal({ext: {eids: [{source: 'adserver.org', uids: [{id: tdid, atype: 1, ext: {rtiPartner: 'TDID'}}]}]}}); + expect(payload.user).to.deep.equal({ ext: { eids: [{ source: 'adserver.org', uids: [{ id: tdid, atype: 1, ext: { rtiPartner: 'TDID' } }] }] } }); }); it('should add criteoId to the payload if included', function () { @@ -801,7 +801,7 @@ describe('triplelift adapter', function () { const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const payload = request.data; expect(payload).to.exist; - expect(payload.user).to.deep.equal({ext: {eids: [{source: 'criteo.com', uids: [{id: id, atype: 1, ext: {rtiPartner: 'criteoId'}}]}]}}); + expect(payload.user).to.deep.equal({ ext: { eids: [{ source: 'criteo.com', uids: [{ id: id, atype: 1, ext: { rtiPartner: 'criteoId' } }] }] } }); }); it('should add tdid and criteoId to the payload if both are included', function () { @@ -893,7 +893,7 @@ describe('triplelift adapter', function () { expect(url).to.match(/(\?|&)us_privacy=1YYY/); }); it('should pass fledge signal when Triplelift is eligible for fledge', function() { - bidderRequest.paapi = {enabled: true}; + bidderRequest.paapi = { enabled: true }; const request = tripleliftAdapterSpec.buildRequests(bidRequests, bidderRequest); const url = request.url; expect(url).to.match(/(\?|&)fledge=true/); @@ -1011,7 +1011,7 @@ describe('triplelift adapter', function () { } }; - const request = tripleliftAdapterSpec.buildRequests(bidRequests, {...bidderRequest, ortb2}); + const request = tripleliftAdapterSpec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }); const { data: payload } = request; expect(payload.ext.ortb2).to.exist; expect(payload.ext.ortb2.site).to.deep.equal({ @@ -1039,7 +1039,7 @@ describe('triplelift adapter', function () { sens: sens, } } - const request = tripleliftAdapterSpec.buildRequests(bidRequests, {...bidderRequest, ortb2}); + const request = tripleliftAdapterSpec.buildRequests(bidRequests, { ...bidderRequest, ortb2 }); const { data: payload } = request; expect(payload.ext.fpd.user).to.not.exist; expect(payload.ext.fpd.context.ext.data).to.haveOwnProperty('category'); @@ -1355,7 +1355,7 @@ describe('triplelift adapter', function () { meta: {} } ]; - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result).to.have.length(4); expect(Object.keys(result[0])).to.have.members(Object.keys(expectedResponse[0])); expect(Object.keys(result[1])).to.have.members(Object.keys(expectedResponse[1])); @@ -1364,7 +1364,7 @@ describe('triplelift adapter', function () { }); it('should identify format of bid and respond accordingly', function() { - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result[0].meta.mediaType).to.equal('native'); expect(result[1].mediaType).to.equal('video'); expect(result[1].meta.mediaType).to.equal('video'); @@ -1377,25 +1377,25 @@ describe('triplelift adapter', function () { }) it('should return multiple responses to support SRA', function () { - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result).to.have.length(4); }); it('should include the advertiser name in the meta field if available', function () { - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result[0].meta.advertiserName).to.equal('fake advertiser name'); expect(result[1].meta).to.not.have.key('advertiserName'); }); it('should include the advertiser domain array in the meta field if available', function () { - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result[0].meta.advertiserDomains[0]).to.equal('basspro.com'); expect(result[0].meta.advertiserDomains[1]).to.equal('internetalerts.org'); expect(result[1].meta).to.not.have.key('advertiserDomains'); }); it('should include networkId in the meta field if available', function () { - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result[1].meta.networkId).to.equal('10092'); expect(result[2].meta.networkId).to.equal('5989'); expect(result[3].meta.networkId).to.equal('5989'); @@ -1427,7 +1427,7 @@ describe('triplelift adapter', function () { } ]; - const result = tripleliftAdapterSpec.interpretResponse(response, {bidderRequest}); + const result = tripleliftAdapterSpec.interpretResponse(response, { bidderRequest }); expect(result).to.have.property('bids'); expect(result).to.have.property('paapi'); diff --git a/test/spec/modules/truereachBidAdapter_spec.js b/test/spec/modules/truereachBidAdapter_spec.js index 6b39d46eac4..58b2c2ebf9c 100644 --- a/test/spec/modules/truereachBidAdapter_spec.js +++ b/test/spec/modules/truereachBidAdapter_spec.js @@ -83,7 +83,7 @@ describe('truereachBidAdapterTests', function () { const user_sync_url = 'https://ads-sg.momagic.com/jsp/usersync.jsp'; it('register_iframe_pixel_if_iframeEnabled_is_true', function() { const syncs = spec.getUserSyncs( - {iframeEnabled: true} + { iframeEnabled: true } ); expect(syncs).to.be.an('array'); expect(syncs.length).to.equal(1); @@ -93,7 +93,7 @@ describe('truereachBidAdapterTests', function () { it('if_pixelEnabled_is_true', function() { const syncs = spec.getUserSyncs( - {pixelEnabled: true} + { pixelEnabled: true } ); expect(syncs).to.be.an('array'); expect(syncs.length).to.equal(0); diff --git a/test/spec/modules/trustxBidAdapter_spec.js b/test/spec/modules/trustxBidAdapter_spec.js index ac572027900..2dfc2e7d41f 100644 --- a/test/spec/modules/trustxBidAdapter_spec.js +++ b/test/spec/modules/trustxBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/trustxBidAdapter.js'; -import {BANNER, VIDEO} from 'src/mediaTypes.js'; +import { expect } from 'chai'; +import { spec } from 'modules/trustxBidAdapter.js'; +import { BANNER, VIDEO } from 'src/mediaTypes.js'; import sinon from 'sinon'; -import {config} from 'src/config.js'; +import { config } from 'src/config.js'; const getBannerRequest = () => { return { @@ -21,7 +21,7 @@ const getBannerRequest = () => { mediaTypes: { banner: { sizes: [ - [ 300, 250 ], + [300, 250], ] } }, @@ -437,7 +437,7 @@ describe('trustxBidAdapter', function() { beforeEach(function() { bidderBannerRequest = getBannerRequest(); - mockBidderRequest = {refererInfo: {}}; + mockBidderRequest = { refererInfo: {} }; bidRequestsWithMediaTypes = [{ bidder: 'trustx', @@ -682,7 +682,7 @@ describe('trustxBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; @@ -919,32 +919,36 @@ describe('trustxBidAdapter', function() { }); it('handles empty response', function () { - const EMPTY_RESP = Object.assign({}, bidderResponse, {'body': {}}); + const EMPTY_RESP = Object.assign({}, bidderResponse, { 'body': {} }); const bids = spec.interpretResponse(EMPTY_RESP, bidRequest); expect(bids).to.be.empty; }); it('should return no bids if the response "nurl" and "adm" are missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - price: 8.01 + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + price: 8.01 + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); it('should return no bids if the response "price" is missing', function () { - const SERVER_RESP = Object.assign({}, bidderResponse, {'body': { - seatbid: [{ - bid: [{ - adm: '' + const SERVER_RESP = Object.assign({}, bidderResponse, { + 'body': { + seatbid: [{ + bid: [{ + adm: '' + }] }] - }] - }}); + } + }); const bids = spec.interpretResponse(SERVER_RESP, bidRequest); expect(bids.length).to.equal(0); }); @@ -995,13 +999,13 @@ describe('trustxBidAdapter', function() { expect(opts).to.be.an('array').that.is.empty; }); it('returns non if sync is not allowed', function () { - let opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: false}); + let opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: false }); expect(opts).to.be.an('array').that.is.empty; }); it('iframe sync enabled should return results', function () { - let opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [bidderResponse]); + let opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('iframe'); @@ -1009,7 +1013,7 @@ describe('trustxBidAdapter', function() { }); it('pixel sync enabled should return results', function () { - let opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [bidderResponse]); + let opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); expect(opts[0].type).to.equal('image'); @@ -1017,7 +1021,7 @@ describe('trustxBidAdapter', function() { }); it('all sync enabled should prioritize iframe', function () { - let opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: true}, [bidderResponse]); + let opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: true }, [bidderResponse]); expect(opts.length).to.equal(1); }); @@ -1088,7 +1092,7 @@ describe('trustxBidAdapter', function() { }; // Test with pixel enabled - let opts = spec.getUserSyncs({iframeEnabled: false, pixelEnabled: true}, [realWorldResponse]); + let opts = spec.getUserSyncs({ iframeEnabled: false, pixelEnabled: true }, [realWorldResponse]); // Should return all pixel syncs from all providers expect(opts).to.be.an('array'); @@ -1100,7 +1104,7 @@ describe('trustxBidAdapter', function() { expect(opts.some(s => s.url.includes('sync.trustx.org'))).to.be.true; // Test with iframe enabled - opts = spec.getUserSyncs({iframeEnabled: true, pixelEnabled: false}, [realWorldResponse]); + opts = spec.getUserSyncs({ iframeEnabled: true, pixelEnabled: false }, [realWorldResponse]); // Should return only iframe syncs expect(opts).to.be.an('array'); diff --git a/test/spec/modules/ttdBidAdapter_spec.js b/test/spec/modules/ttdBidAdapter_spec.js index c11378e72cc..9f30f14af99 100644 --- a/test/spec/modules/ttdBidAdapter_spec.js +++ b/test/spec/modules/ttdBidAdapter_spec.js @@ -449,10 +449,10 @@ describe('ttdBidAdapter', function () { } } const requestBody = testBuildRequests( - baseBannerBidRequests, {...baseBidderRequestWithoutRefererDomain, ortb2} + baseBannerBidRequests, { ...baseBidderRequestWithoutRefererDomain, ortb2 } ).data; config.resetConfig(); - expect(requestBody.site.publisher).to.deep.equal({domain: 'https://foo.bar', id: '13144370'}); + expect(requestBody.site.publisher).to.deep.equal({ domain: 'https://foo.bar', id: '13144370' }); }); it('referer domain overrides first party site data publisher domain', function () { @@ -464,7 +464,7 @@ describe('ttdBidAdapter', function () { } }; const requestBody = testBuildRequests( - baseBannerBidRequests, {...baseBidderRequest, ortb2} + baseBannerBidRequests, { ...baseBidderRequest, ortb2 } ).data; config.resetConfig(); expect(requestBody.site.publisher.domain).to.equal(baseBidderRequest.refererInfo.domain); @@ -476,7 +476,7 @@ describe('ttdBidAdapter', function () { keywords: 'highViewability, clothing, holiday shopping' } }; - const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data; + const requestBody = testBuildRequests(baseBannerBidRequests, { ...baseBidderRequest, ortb2 }).data; config.resetConfig(); expect(requestBody.ext.ttdprebid.keywords).to.deep.equal(['highViewability', 'clothing', 'holiday shopping']); }); @@ -485,7 +485,7 @@ describe('ttdBidAdapter', function () { const ortb2 = { bcat: ['IAB1-1', 'IAB2-9'] }; - const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data; + const requestBody = testBuildRequests(baseBannerBidRequests, { ...baseBidderRequest, ortb2 }).data; config.resetConfig(); expect(requestBody.bcat).to.deep.equal(['IAB1-1', 'IAB2-9']); }); @@ -494,7 +494,7 @@ describe('ttdBidAdapter', function () { const ortb2 = { badv: ['adv1.com', 'adv2.com'] }; - const requestBody = testBuildRequests(baseBannerBidRequests, {...baseBidderRequest, ortb2}).data; + const requestBody = testBuildRequests(baseBannerBidRequests, { ...baseBidderRequest, ortb2 }).data; config.resetConfig(); expect(requestBody.badv).to.deep.equal(['adv1.com', 'adv2.com']); }); @@ -543,7 +543,7 @@ describe('ttdBidAdapter', function () { it('adds coppa consent info to the request', function () { const clonedBidderRequest = deepClone(baseBidderRequest); - config.setConfig({coppa: true}); + config.setConfig({ coppa: true }); const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; config.resetConfig(); expect(requestBody.regs.coppa).to.equal(1); @@ -556,7 +556,7 @@ describe('ttdBidAdapter', function () { gpp_sid: [6, 7] } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; config.resetConfig(); expect(requestBody.regs.gpp).to.equal('somegppstring'); @@ -630,7 +630,7 @@ describe('ttdBidAdapter', function () { keywords: 'power tools, drills' } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; expect(requestBody.site.name).to.equal('example'); expect(requestBody.site.domain).to.equal('page.example.com'); @@ -678,7 +678,7 @@ describe('ttdBidAdapter', function () { } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; validateExtFirstPartyData(requestBody.site.ext) @@ -693,7 +693,7 @@ describe('ttdBidAdapter', function () { } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; validateExtFirstPartyData(requestBody.user.ext) @@ -725,7 +725,7 @@ describe('ttdBidAdapter', function () { } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; validateExtFirstPartyData(requestBody.app.ext) @@ -740,7 +740,7 @@ describe('ttdBidAdapter', function () { } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; validateExtFirstPartyData(requestBody.device.ext) @@ -755,7 +755,7 @@ describe('ttdBidAdapter', function () { } }; - const clonedBidderRequest = {...deepClone(baseBidderRequest), ortb2}; + const clonedBidderRequest = { ...deepClone(baseBidderRequest), ortb2 }; const requestBody = testBuildRequests(baseBannerBidRequests, clonedBidderRequest).data; validateExtFirstPartyData(requestBody.imp[0].pmp.ext) diff --git a/test/spec/modules/twistDigitalBidAdapter_spec.js b/test/spec/modules/twistDigitalBidAdapter_spec.js index ea3779c8be8..e4c6c2777b4 100644 --- a/test/spec/modules/twistDigitalBidAdapter_spec.js +++ b/test/spec/modules/twistDigitalBidAdapter_spec.js @@ -1,15 +1,15 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, createDomain, storage } from 'modules/twistDigitalBidAdapter.js'; import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; -import {deepSetValue} from 'src/utils.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; +import { deepSetValue } from 'src/utils.js'; import { extractPID, extractCID, @@ -20,7 +20,7 @@ import { tryParseJSON, getUniqueDealId } from '../../../libraries/vidazooUtils/bidderUtils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['britepoolid', 'criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'parrableId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -103,9 +103,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -122,7 +122,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -149,8 +149,8 @@ const BIDDER_REQUEST = { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }] } @@ -164,9 +164,9 @@ const BIDDER_REQUEST = { user: { data: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], } @@ -215,21 +215,21 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, "site": { "cat": ["IAB2"], "content": { "data": [{ - "ext": {"segtax": 7}, + "ext": { "segtax": 7 }, "name": "example.com", - "segments": [{"id": "segId1"}, {"id": "segId2"}] + "segments": [{ "id": "segId1" }, { "id": "segId2" }] }], "language": "en" }, "pagecat": ["IAB2-2"] }, "user": { - "data": [{"ext": {"segclass": "1", "segtax": 600}, "name": "example.com", "segment": [{"id": "243"}]}] + "data": [{ "ext": { "segclass": "1", "segtax": 600 }, "name": "example.com", "segment": [{ "id": "243" }] }] } }; @@ -243,7 +243,7 @@ const REQUEST = { function getTopWindowQueryParams() { try { - const parsedUrl = utils.parseUrl(window.top.document.URL, {decodeSearchAsString: true}); + const parsedUrl = utils.parseUrl(window.top.document.URL, { decodeSearchAsString: true }); return parsedUrl.search; } catch (e) { return ''; @@ -369,9 +369,9 @@ describe('TwistDigitalBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -387,15 +387,15 @@ describe('TwistDigitalBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], uniqueDealId: `${hashUrl}_${Date.now().toString()}`, @@ -453,9 +453,9 @@ describe('TwistDigitalBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -493,15 +493,15 @@ describe('TwistDigitalBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ] } @@ -544,9 +544,9 @@ describe('TwistDigitalBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -582,15 +582,15 @@ describe('TwistDigitalBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ] }; @@ -606,10 +606,12 @@ describe('TwistDigitalBidAdapter', function () { expect(requests[0]).to.deep.equal({ method: 'POST', url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`, - data: {bids: [ - {...REQUEST_DATA, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp}, - {...REQUEST_DATA2, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp} - ]} + data: { + bids: [ + { ...REQUEST_DATA, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp }, + { ...REQUEST_DATA2, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp } + ] + } }); }); @@ -642,7 +644,7 @@ describe('TwistDigitalBidAdapter', function () { it('should set fledge correctly if enabled', function () { config.resetConfig(); const bidderRequest = utils.deepClone(BIDDER_REQUEST); - bidderRequest.paapi = {enabled: true}; + bidderRequest.paapi = { enabled: true }; deepSetValue(bidderRequest, 'ortb2Imp.ext.ae', 1); const requests = adapter.buildRequests([BID], bidderRequest); expect(requests[0].data.fledge).to.equal(1); @@ -657,7 +659,7 @@ describe('TwistDigitalBidAdapter', function () { describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -666,7 +668,7 @@ describe('TwistDigitalBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.twist.win/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -674,7 +676,7 @@ describe('TwistDigitalBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.twist.win/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -686,7 +688,7 @@ describe('TwistDigitalBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.twist.win/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -701,12 +703,12 @@ describe('TwistDigitalBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -802,9 +804,9 @@ describe('TwistDigitalBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -825,7 +827,7 @@ describe('TwistDigitalBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -836,11 +838,11 @@ describe('TwistDigitalBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -855,7 +857,7 @@ describe('TwistDigitalBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -870,11 +872,11 @@ describe('TwistDigitalBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -887,18 +889,18 @@ describe('TwistDigitalBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -971,7 +973,7 @@ describe('TwistDigitalBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -987,8 +989,8 @@ describe('TwistDigitalBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js b/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js index 997586c195e..75822849e73 100644 --- a/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js +++ b/test/spec/modules/ucfunnelAnalyticsAdapter_spec.js @@ -3,7 +3,7 @@ import { ANALYTICS_VERSION, BIDDER_STATUS } from 'modules/ucfunnelAnalyticsAdapter.js'; -import {expect} from 'chai'; +import { expect } from 'chai'; const events = require('src/events'); const constants = require('src/constants.js'); @@ -89,7 +89,7 @@ describe('ucfunnel Prebid AnalyticsAdapter Testing', function () { }); describe('#getCachedAuction()', function() { - const existing = {timeoutBids: [{}]}; + const existing = { timeoutBids: [{}] }; ucfunnelAnalyticsAdapter.cachedAuctions['test_auction_id'] = existing; it('should get the existing cached object if it exists', function() { diff --git a/test/spec/modules/ucfunnelBidAdapter_spec.js b/test/spec/modules/ucfunnelBidAdapter_spec.js index 3e78ee4d0d4..3a41c8209f1 100644 --- a/test/spec/modules/ucfunnelBidAdapter_spec.js +++ b/test/spec/modules/ucfunnelBidAdapter_spec.js @@ -1,7 +1,7 @@ import { expect } from 'chai'; import { spec } from 'modules/ucfunnelBidAdapter.js'; -import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes.js'; -import {deepClone} from '../../../src/utils.js'; +import { BANNER, VIDEO, NATIVE } from 'src/mediaTypes.js'; +import { deepClone } from '../../../src/utils.js'; const URL = 'https://hb.aralego.com/header'; const BIDDER_CODE = 'ucfunnel'; @@ -15,13 +15,13 @@ const bidderRequest = { const userId = { 'criteoId': 'vYlICF9oREZlTHBGRVdrJTJCUUJnc3U2ckNVaXhrV1JWVUZVSUxzZmJlcnJZR0ZxbVhFRnU5bDAlMkJaUWwxWTlNcmdEeHFrJTJGajBWVlV4T3lFQ0FyRVcxNyUyQlIxa0lLSlFhcWJpTm9PSkdPVkx0JTJCbzlQRTQlM0Q', - 'id5id': {'uid': 'ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA'}, + 'id5id': { 'uid': 'ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA' }, 'netId': 'fH5A3n2O8_CZZyPoJVD-eabc6ECb7jhxCicsds7qSg', - 'parrableId': {'eid': '01.1608624401.fe44bca9b96873084a0d4e9d0ac5729f13790ba8f8e58fa4707b6b3c096df91c6b5f254992bdad4ab1dd4a89919081e9b877d7a039ac3183709277665bac124f28e277d109f0ff965058'}, + 'parrableId': { 'eid': '01.1608624401.fe44bca9b96873084a0d4e9d0ac5729f13790ba8f8e58fa4707b6b3c096df91c6b5f254992bdad4ab1dd4a89919081e9b877d7a039ac3183709277665bac124f28e277d109f0ff965058' }, 'pubcid': 'd8aa10fa-d86c-451d-aad8-5f16162a9e64', 'tdid': 'D6885E90-2A7A-4E0F-87CB-7734ED1B99A3', 'haloId': {}, - 'uid2': {'id': 'eb33b0cb-8d35-4722-b9c0-1a31d4064888'}, + 'uid2': { 'id': 'eb33b0cb-8d35-4722-b9c0-1a31d4064888' }, 'connectid': '4567' } @@ -177,7 +177,7 @@ describe('ucfunnel Adapter', function () { it('should attach request data', function () { const data = request[0].data; - const [ width, height ] = validBannerBidReq.sizes[0]; + const [width, height] = validBannerBidReq.sizes[0]; expect(data.usprivacy).to.equal('1YNN'); expect(data.adid).to.equal('ad-34BBD2AA24B678BBFD4E7B9EE3B872D'); expect(data.w).to.equal(width); @@ -190,7 +190,7 @@ describe('ucfunnel Adapter', function () { const sizes = [[300, 250], [336, 280]]; const format = '300,250;336,280'; validBannerBidReq.sizes = sizes; - const requests = spec.buildRequests([ validBannerBidReq ], bidderRequest); + const requests = spec.buildRequests([validBannerBidReq], bidderRequest); const data = requests[0].data; expect(data.w).to.equal(sizes[0][0]); expect(data.h).to.equal(sizes[0][1]); @@ -205,7 +205,7 @@ describe('ucfunnel Adapter', function () { floor: 2.02 } }; - const requests = spec.buildRequests([ bid ], bidderRequest); + const requests = spec.buildRequests([bid], bidderRequest); const data = requests[0].data; expect(data.fp).to.equal(2.02); }); @@ -213,7 +213,7 @@ describe('ucfunnel Adapter', function () { it('should set bidfloor if configured', function() { const bid = deepClone(validBannerBidReq); bid.params.bidfloor = 2.01; - const requests = spec.buildRequests([ bid ], bidderRequest); + const requests = spec.buildRequests([bid], bidderRequest); const data = requests[0].data; expect(data.fp).to.equal(2.01); }); @@ -227,7 +227,7 @@ describe('ucfunnel Adapter', function () { } }; bid.params.bidfloor = 2.01; - const requests = spec.buildRequests([ bid ], bidderRequest); + const requests = spec.buildRequests([bid], bidderRequest); const data = requests[0].data; expect(data.fp).to.equal(2.01); }); @@ -237,8 +237,8 @@ describe('ucfunnel Adapter', function () { describe('should support banner', function () { let request, result; before(() => { - request = spec.buildRequests([ validBannerBidReq ], bidderRequest); - result = spec.interpretResponse({body: validBannerBidRes}, request[0]); + request = spec.buildRequests([validBannerBidReq], bidderRequest); + result = spec.interpretResponse({ body: validBannerBidRes }, request[0]); }); it('should build bid array for banner', function () { @@ -260,8 +260,8 @@ describe('ucfunnel Adapter', function () { describe('handle banner no ad', function () { let request, result; before(() => { - request = spec.buildRequests([ validBannerBidReq ], bidderRequest); - result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); + request = spec.buildRequests([validBannerBidReq], bidderRequest); + result = spec.interpretResponse({ body: invalidBannerBidRes }, request[0]); }) it('should build bid array for banner', function () { expect(result.length).to.equal(1); @@ -281,8 +281,8 @@ describe('ucfunnel Adapter', function () { describe('handle banner cpm under bidfloor', function () { let request, result; before(() => { - request = spec.buildRequests([ validBannerBidReq ], bidderRequest); - result = spec.interpretResponse({body: invalidBannerBidRes}, request[0]); + request = spec.buildRequests([validBannerBidReq], bidderRequest); + result = spec.interpretResponse({ body: invalidBannerBidRes }, request[0]); }) it('should build bid array for banner', function () { expect(result.length).to.equal(1); @@ -302,8 +302,8 @@ describe('ucfunnel Adapter', function () { describe('should support video', function () { let request, result; before(() => { - request = spec.buildRequests([ validVideoBidReq ], bidderRequest); - result = spec.interpretResponse({body: validVideoBidRes}, request[0]); + request = spec.buildRequests([validVideoBidReq], bidderRequest); + result = spec.interpretResponse({ body: validVideoBidRes }, request[0]); }) it('should build bid array', function () { expect(result.length).to.equal(1); @@ -325,8 +325,8 @@ describe('ucfunnel Adapter', function () { describe('should support native', function () { let request, result; before(() => { - request = spec.buildRequests([ validNativeBidReq ], bidderRequest); - result = spec.interpretResponse({body: validNativeBidRes}, request[0]); + request = spec.buildRequests([validNativeBidReq], bidderRequest); + result = spec.interpretResponse({ body: validNativeBidRes }, request[0]); }) it('should build bid array', function () { expect(result.length).to.equal(1); @@ -349,7 +349,7 @@ describe('ucfunnel Adapter', function () { describe('cookie sync', function () { describe('cookie sync iframe', function () { - const result = spec.getUserSyncs({'iframeEnabled': true}, null, gdprConsent); + const result = spec.getUserSyncs({ 'iframeEnabled': true }, null, gdprConsent); it('should return cookie sync iframe info', function () { expect(result[0].type).to.equal('iframe'); @@ -357,7 +357,7 @@ describe('ucfunnel Adapter', function () { }); }); describe('cookie sync image', function () { - const result = spec.getUserSyncs({'pixelEnabled': true}, null, gdprConsent); + const result = spec.getUserSyncs({ 'pixelEnabled': true }, null, gdprConsent); it('should return cookie sync image info', function () { expect(result[0].type).to.equal('image'); expect(result[0].url).to.equal('https://sync.aralego.com/idSync?gdpr=1&euconsent-v2=CO9rhBTO9rhBTAcABBENBCCsAP_AAH_AACiQHItf_X_fb3_j-_59_9t0eY1f9_7_v20zjgeds-8Nyd_X_L8X42M7vB36pq4KuR4Eu3LBIQdlHOHcTUmw6IkVqTPsbk2Mr7NKJ7PEinMbe2dYGH9_n9XTuZKY79_s___z__-__v__7_f_r-3_3_vp9V---3YHIgEmGpfARZiWOBJNGlUKIEIVxIdACACihGFomsICVwU7K4CP0EDABAagIwIgQYgoxZBAAAAAElEQEgB4IBEARAIAAQAqQEIACNAEFgBIGAQACgGhYARQBCBIQZHBUcpgQESLRQTyVgCUXexhhCGUUANAg4AA.YAAAAAAAAAAA&'); diff --git a/test/spec/modules/uid2IdSystem_helpers.js b/test/spec/modules/uid2IdSystem_helpers.js index ec9eef1d488..433f574bc82 100644 --- a/test/spec/modules/uid2IdSystem_helpers.js +++ b/test/spec/modules/uid2IdSystem_helpers.js @@ -1,6 +1,6 @@ -import {setConsentConfig} from 'modules/consentManagementTcf.js'; -import {server} from 'test/mocks/xhr.js'; -import {coreStorage, startAuctionHook} from 'modules/userId/index.js'; +import { setConsentConfig } from 'modules/consentManagementTcf.js'; +import { server } from 'test/mocks/xhr.js'; +import { coreStorage, startAuctionHook } from 'modules/userId/index.js'; const msIn12Hours = 60 * 60 * 12 * 1000; const expireCookieDate = 'Thu, 01 Jan 1970 00:00:01 GMT'; @@ -17,17 +17,17 @@ export const runAuction = async () => { const adUnits = [{ code: 'adUnit-code', - mediaTypes: {banner: {}, native: {}}, + mediaTypes: { banner: {}, native: {} }, sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}] + bids: [{ bidder: 'sampleBidder', params: { placementId: 'banner-only-bidder' } }] }]; - const ortb2Fragments = {global: {}, bidder: {}}; + const ortb2Fragments = { global: {}, bidder: {} }; return new Promise(function(resolve) { startAuctionHook(function() { const bid = Object.assign({}, adUnits[0].bids[0]); bid.userIdAsEids = (ortb2Fragments.global.user?.ext?.eids ?? []).concat(ortb2Fragments.bidder[bid.bidder]?.user?.ext?.eids ?? []); resolve(bid); - }, {adUnits, ortb2Fragments}); + }, { adUnits, ortb2Fragments }); }); } diff --git a/test/spec/modules/uid2IdSystem_spec.js b/test/spec/modules/uid2IdSystem_spec.js index f8980bd3961..7ad45ecb74e 100644 --- a/test/spec/modules/uid2IdSystem_spec.js +++ b/test/spec/modules/uid2IdSystem_spec.js @@ -1,16 +1,16 @@ -import {attachIdSystem, coreStorage, init, setSubmoduleRegistry} from 'modules/userId/index.js'; -import {config} from 'src/config.js'; +import { attachIdSystem, coreStorage, init, setSubmoduleRegistry } from 'modules/userId/index.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import { uid2IdSubmodule } from 'modules/uid2IdSystem.js'; -import {requestBids} from '../../../src/prebid.js'; +import { requestBids } from '../../../src/prebid.js'; import 'modules/consentManagementTcf.js'; import { getGlobal } from 'src/prebidGlobal.js'; import { configureTimerInterceptors } from 'test/mocks/timers.js'; import { cookieHelpers, runAuction, apiHelpers, setGdprApplies } from './uid2IdSystem_helpers.js'; -import {hook} from 'src/hook.js'; -import {uninstall as uninstallTcfControl} from 'modules/tcfControl.js'; -import {server} from 'test/mocks/xhr'; -import {createEidsArray} from '../../../modules/userId/eids.js'; +import { hook } from 'src/hook.js'; +import { uninstall as uninstallTcfControl } from 'modules/tcfControl.js'; +import { server } from 'test/mocks/xhr'; +import { createEidsArray } from '../../../modules/userId/eids.js'; const expect = require('chai').expect; @@ -26,16 +26,16 @@ const refreshedToken = 'refreshed-advertising-token'; const clientSideGeneratedToken = 'client-side-generated-advertising-token'; const optoutToken = 'optout-token'; -const legacyConfigParams = {storage: null}; +const legacyConfigParams = { storage: null }; const serverCookieConfigParams = { uid2ServerCookie: publisherCookieName }; const newServerCookieConfigParams = { uid2Cookie: publisherCookieName }; const cstgConfigParams = { serverPublicKey: 'UID2-X-L-24B8a/eLYBmRkXA9yPgRZt+ouKbXewG2OPs23+ov3JC8mtYJBCx6AxGwJ4MlwUcguebhdDp2CvzsCgS9ogwwGA==', subscriptionId: 'subscription-id' } -const makeUid2IdentityContainer = (token) => ({uid2: {id: token}}); -const makeUid2OptoutContainer = (token) => ({uid2: {optout: true}}); +const makeUid2IdentityContainer = (token) => ({ uid2: { id: token } }); +const makeUid2OptoutContainer = (token) => ({ uid2: { optout: true } }); let useLocalStorage = false; const makePrebidConfig = (params = null, extraSettings = {}, debug = false) => ({ - userSync: { auctionDelay: extraSettings.auctionDelay ?? auctionDelayMs, ...(extraSettings.syncDelay !== undefined && {syncDelay: extraSettings.syncDelay}), userIds: [{name: 'uid2', params: {storage: useLocalStorage ? 'localStorage' : 'cookie', ...params}}] }, debug + userSync: { auctionDelay: extraSettings.auctionDelay ?? auctionDelayMs, ...(extraSettings.syncDelay !== undefined && { syncDelay: extraSettings.syncDelay }), userIds: [{ name: 'uid2', params: { storage: useLocalStorage ? 'localStorage' : 'cookie', ...params } }] }, debug }); const makeOriginalIdentity = (identity, salt = 1) => ({ identity: utils.cyrb53Hash(identity, salt), @@ -184,14 +184,14 @@ describe(`UID2 module`, function () { describe('Configuration', function() { it('When no baseUrl is provided in config, the module calls the production endpoint', async function () { const uid2Token = apiHelpers.makeTokenResponse(initialToken, true, true); - config.setConfig(makePrebidConfig({uid2Token})); + config.setConfig(makePrebidConfig({ uid2Token })); await runAuction(); expect(server.requests[0]?.url).to.have.string('https://prod.uidapi.com/v2/token/refresh'); }); it('When a baseUrl is provided in config, the module calls the provided endpoint', async function () { const uid2Token = apiHelpers.makeTokenResponse(initialToken, true, true); - config.setConfig(makePrebidConfig({uid2Token, uid2ApiBase: 'https://operator-integ.uidapi.com'})); + config.setConfig(makePrebidConfig({ uid2Token, uid2ApiBase: 'https://operator-integ.uidapi.com' })); await runAuction(); expect(server.requests[0]?.url).to.have.string('https://operator-integ.uidapi.com/v2/token/refresh'); }); @@ -199,7 +199,7 @@ describe(`UID2 module`, function () { it('When a legacy value is provided directly in configuration, it is passed on', async function() { const valueConfig = makePrebidConfig(); - valueConfig.userSync.userIds[0].value = {uid2: {id: legacyToken}} + valueConfig.userSync.userIds[0].value = { uid2: { id: legacyToken } } config.setConfig(valueConfig); const bid = await runAuction(); @@ -231,14 +231,14 @@ describe(`UID2 module`, function () { it('and a server cookie is used with a valid server cookie, it should provide the server cookie', async function() { cookieHelpers.setPublisherCookie(publisherCookieName, apiHelpers.makeTokenResponse(initialToken)); await createLegacyTest(newServerCookieConfigParams, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken])(); }); it('and a token is provided in config, it should provide the config token', - createLegacyTest({uid2Token: apiHelpers.makeTokenResponse(initialToken)}, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken])); + createLegacyTest({ uid2Token: apiHelpers.makeTokenResponse(initialToken) }, [(bid) => expectToken(bid, initialToken), expectNoLegacyToken])); it('and GDPR applies, no identity should be provided to the auction', createLegacyTest(legacyConfigParams, [expectNoIdentity], true)); it('and GDPR applies, when getId is called directly it provides no identity', () => { coreStorage.setCookie(moduleCookieName, legacyToken, cookieHelpers.getFutureCookieExpiry()); const consentConfig = setGdprApplies(); const configObj = makePrebidConfig(legacyConfigParams); - const result = uid2IdSubmodule.getId(configObj.userSync.userIds[0], {gdpr: consentConfig.consentData}); + const result = uid2IdSubmodule.getId(configObj.userSync.userIds[0], { gdpr: consentConfig.consentData }); expect(result?.id).to.not.exist; }); @@ -264,7 +264,7 @@ describe(`UID2 module`, function () { { name: 'Token provided in config call', setConfig: (token, extraConfig = {}) => { - const gen = makePrebidConfig({uid2Token: token}, extraConfig); + const gen = makePrebidConfig({ uid2Token: token }, extraConfig); return config.setConfig(gen); }, }, @@ -325,7 +325,7 @@ describe(`UID2 module`, function () { it('the refreshed value from the cookie is used', async function() { const initialIdentity = apiHelpers.makeTokenResponse(initialToken, true, true); const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken); - const moduleCookie = {originalToken: initialIdentity, latestToken: refreshedIdentity}; + const moduleCookie = { originalToken: initialIdentity, latestToken: refreshedIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); scenario.setConfig(initialIdentity); @@ -352,7 +352,7 @@ describe(`UID2 module`, function () { describe(`When a current token which should be refreshed is provided, and the auction is set to run immediately`, function() { beforeEach(function() { - scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true), {auctionDelay: 0, syncDelay: 1}); + scenario.setConfig(apiHelpers.makeTokenResponse(initialToken, true), { auctionDelay: 0, syncDelay: 1 }); }); testApiSuccessAndFailure(async function() { apiHelpers.respondAfterDelay(10, server); @@ -496,7 +496,7 @@ describe(`UID2 module`, function () { describe('When the storedToken is valid', function() { it('it should use the stored token in the auction', async function() { const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken); - const moduleCookie = {originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({ ...cstgConfigParams, email: 'test@test.com', auctionDelay: 0, syncDelay: 1 })); const bid = await runAuction(); @@ -507,7 +507,7 @@ describe(`UID2 module`, function () { describe('When the storedToken is expired and can be refreshed ', function() { testApiSuccessAndFailure(async function(apiSucceeds) { const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken, true, true); - const moduleCookie = {originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({ ...cstgConfigParams, email: 'test@test.com' })); apiHelpers.respondAfterDelay(auctionDelayMs / 10, server); @@ -522,7 +522,7 @@ describe(`UID2 module`, function () { describe('When the storedToken is expired for refresh', function() { testApiSuccessAndFailure(async function(apiSucceeds) { const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken, true, true, true); - const moduleCookie = {originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('test@test.com'), latestToken: refreshedIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({ ...cstgConfigParams, email: 'test@test.com' })); apiHelpers.respondAfterDelay(auctionDelayMs / 10, server); @@ -537,7 +537,7 @@ describe(`UID2 module`, function () { it('when originalIdentity not match, the auction should has no uid2', async function() { const refreshedIdentity = apiHelpers.makeTokenResponse(refreshedToken); - const moduleCookie = {originalIdentity: makeOriginalIdentity('123@test.com'), latestToken: refreshedIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('123@test.com'), latestToken: refreshedIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({ ...cstgConfigParams, email: 'test@test.com' })); const bid = await runAuction(); @@ -613,7 +613,7 @@ describe(`UID2 module`, function () { describe('when there is a non-cstg-derived token in the module cookie', function () { it('the auction use stored token if it is valid', async function () { const originalIdentity = apiHelpers.makeTokenResponse(initialToken); - const moduleCookie = {originalToken: originalIdentity, latestToken: originalIdentity}; + const moduleCookie = { originalToken: originalIdentity, latestToken: originalIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({})); const bid = await runAuction(); @@ -622,7 +622,7 @@ describe(`UID2 module`, function () { it('the auction should has no uid2 if stored token is invalid', async function () { const originalIdentity = apiHelpers.makeTokenResponse(initialToken, true, true, true); - const moduleCookie = {originalToken: originalIdentity, latestToken: originalIdentity}; + const moduleCookie = { originalToken: originalIdentity, latestToken: originalIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({})); const bid = await runAuction(); @@ -633,7 +633,7 @@ describe(`UID2 module`, function () { describe('when there is a cstg-derived token in the module cookie', function () { it('the auction use stored token if it is valid', async function () { const originalIdentity = apiHelpers.makeTokenResponse(initialToken); - const moduleCookie = {originalIdentity: makeOriginalIdentity('123@test.com'), originalToken: originalIdentity, latestToken: originalIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('123@test.com'), originalToken: originalIdentity, latestToken: originalIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({})); const bid = await runAuction(); @@ -642,7 +642,7 @@ describe(`UID2 module`, function () { it('the auction should has no uid2 if stored token is invalid', async function () { const originalIdentity = apiHelpers.makeTokenResponse(initialToken, true, true, true); - const moduleCookie = {originalIdentity: makeOriginalIdentity('123@test.com'), originalToken: originalIdentity, latestToken: originalIdentity}; + const moduleCookie = { originalIdentity: makeOriginalIdentity('123@test.com'), originalToken: originalIdentity, latestToken: originalIdentity }; coreStorage.setCookie(moduleCookieName, JSON.stringify(moduleCookie), cookieHelpers.getFutureCookieExpiry()); config.setConfig(makePrebidConfig({})); const bid = await runAuction(); @@ -659,7 +659,7 @@ describe(`UID2 module`, function () { describe('eid', () => { it('uid2', function() { const userId = { - uid2: {'id': 'Sample_AD_Token'} + uid2: { 'id': 'Sample_AD_Token' } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -674,7 +674,7 @@ describe(`UID2 module`, function () { it('uid2 with ext', function() { const userId = { - uid2: {'id': 'Sample_AD_Token', 'ext': {'provider': 'some.provider.com'}} + uid2: { 'id': 'Sample_AD_Token', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); diff --git a/test/spec/modules/undertoneBidAdapter_spec.js b/test/spec/modules/undertoneBidAdapter_spec.js index ed531371af7..f4f85a110a1 100644 --- a/test/spec/modules/undertoneBidAdapter_spec.js +++ b/test/spec/modules/undertoneBidAdapter_spec.js @@ -1,7 +1,7 @@ -import {expect} from 'chai'; -import {spec} from 'modules/undertoneBidAdapter.js'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {deepClone, getWinDimensions} from '../../../src/utils.js'; +import { expect } from 'chai'; +import { spec } from 'modules/undertoneBidAdapter.js'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { deepClone, getWinDimensions } from '../../../src/utils.js'; const URL = 'https://hb.undertone.com/hb'; const BIDDER_CODE = 'undertone'; @@ -153,7 +153,7 @@ const bidReqUserIds = [{ userId: { idl_env: '1111', tdid: '123456', - digitrustid: {data: {id: 'DTID', keyv: 4, privacy: {optout: false}, producer: 'ABC', version: 2}}, + digitrustid: { data: { id: 'DTID', keyv: 4, privacy: { optout: false }, producer: 'ABC', version: 2 } }, id5id: { uid: '1111' } } }, @@ -525,12 +525,12 @@ describe('Undertone Adapter', () => { describe('interpretResponse', () => { it('should build bid array', () => { - const result = spec.interpretResponse({body: bidResponse}); + const result = spec.interpretResponse({ body: bidResponse }); expect(result.length).to.equal(1); }); it('should have all relevant fields', () => { - const result = spec.interpretResponse({body: bidResponse}); + const result = spec.interpretResponse({ body: bidResponse }); const bid = result[0]; expect(bid.requestId).to.equal('263be71e91dd9d'); @@ -545,8 +545,8 @@ describe('Undertone Adapter', () => { }); it('should return empty array when response is incorrect', () => { - expect(spec.interpretResponse({body: {}}).length).to.equal(0); - expect(spec.interpretResponse({body: []}).length).to.equal(0); + expect(spec.interpretResponse({ body: {} }).length).to.equal(0); + expect(spec.interpretResponse({ body: [] }).length).to.equal(0); }); it('should only use valid bid responses', () => { @@ -554,7 +554,7 @@ describe('Undertone Adapter', () => { }); it('should detect video response', () => { - const videoResult = spec.interpretResponse({body: bidVideoResponse}); + const videoResult = spec.interpretResponse({ body: bidVideoResponse }); const vbid = videoResult[0]; expect(vbid.mediaType).to.equal('video'); @@ -573,7 +573,7 @@ describe('Undertone Adapter', () => { }, { name: 'with iframe and gdpr on', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }], expect: { type: 'iframe', pixels: ['https://cdn.undertone.com/js/usersync.html?gdpr=1&gdprstr=234234'] @@ -589,7 +589,7 @@ describe('Undertone Adapter', () => { }, { name: 'with iframe and no gdpr off or ccpa', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: false}], + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, { gdprApplies: false }], expect: { type: 'iframe', pixels: ['https://cdn.undertone.com/js/usersync.html?gdpr=0&gdprstr='] @@ -597,7 +597,7 @@ describe('Undertone Adapter', () => { }, { name: 'with iframe and gdpr and ccpa', - arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], + arguments: [{ iframeEnabled: true, pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }, 'YN12'], expect: { type: 'iframe', pixels: ['https://cdn.undertone.com/js/usersync.html?gdpr=1&gdprstr=234234&ccpa=YN12'] @@ -614,7 +614,7 @@ describe('Undertone Adapter', () => { }, { name: 'with pixels and gdpr on', - arguments: [{ pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}], + arguments: [{ pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }], expect: { type: 'image', pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2&gdpr=1&gdprstr=234234', @@ -632,7 +632,7 @@ describe('Undertone Adapter', () => { }, { name: 'with pixels and gdpr off', - arguments: [{ pixelEnabled: true }, {}, {gdprApplies: false}], + arguments: [{ pixelEnabled: true }, {}, { gdprApplies: false }], expect: { type: 'image', pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2&gdpr=0&gdprstr=', @@ -641,7 +641,7 @@ describe('Undertone Adapter', () => { }, { name: 'with pixels and gdpr and ccpa on', - arguments: [{ pixelEnabled: true }, {}, {gdprApplies: true, consentString: '234234'}, 'YN12'], + arguments: [{ pixelEnabled: true }, {}, { gdprApplies: true, consentString: '234234' }, 'YN12'], expect: { type: 'image', pixels: ['https://usr.undertone.com/userPixel/syncOne?id=1&of=2&gdpr=1&gdprstr=234234&ccpa=YN12', diff --git a/test/spec/modules/unicornBidAdapter_spec.js b/test/spec/modules/unicornBidAdapter_spec.js index 7e6d41fc85e..abf3bac8e88 100644 --- a/test/spec/modules/unicornBidAdapter_spec.js +++ b/test/spec/modules/unicornBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {assert, expect} from 'chai'; +import { assert, expect } from 'chai'; import * as utils from 'src/utils.js'; -import {spec} from 'modules/unicornBidAdapter.js'; +import { spec } from 'modules/unicornBidAdapter.js'; import * as _ from 'lodash'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; const bidRequests = [ { diff --git a/test/spec/modules/unifiedIdSystem_spec.js b/test/spec/modules/unifiedIdSystem_spec.js index b5d13c57f5c..b7d5426f337 100644 --- a/test/spec/modules/unifiedIdSystem_spec.js +++ b/test/spec/modules/unifiedIdSystem_spec.js @@ -1,17 +1,17 @@ -import {attachIdSystem} from '../../../modules/userId/index.js'; -import {unifiedIdSubmodule} from '../../../modules/unifiedIdSystem.js'; -import {createEidsArray} from '../../../modules/userId/eids.js'; -import {expect} from 'chai/index.mjs'; -import {server} from 'test/mocks/xhr.js'; +import { attachIdSystem } from '../../../modules/userId/index.js'; +import { unifiedIdSubmodule } from '../../../modules/unifiedIdSystem.js'; +import { createEidsArray } from '../../../modules/userId/eids.js'; +import { expect } from 'chai/index.mjs'; +import { server } from 'test/mocks/xhr.js'; describe('Unified ID', () => { describe('getId', () => { it('should use provided URL', () => { - unifiedIdSubmodule.getId({params: {url: 'https://given-url/'}}).callback(); + unifiedIdSubmodule.getId({ params: { url: 'https://given-url/' } }).callback(); expect(server.requests[0].url).to.eql('https://given-url/'); }); it('should use partner URL', () => { - unifiedIdSubmodule.getId({params: {partner: 'rubicon'}}).callback(); + unifiedIdSubmodule.getId({ params: { partner: 'rubicon' } }).callback(); expect(server.requests[0].url).to.equal('https://match.adsrvr.org/track/rid?ttd_pid=rubicon&fmt=json'); }); }); @@ -30,13 +30,13 @@ describe('Unified ID', () => { inserter: 'adserver.org', matcher: 'adserver.org', mm: 4, - uids: [{id: 'some-random-id-value', atype: 1, ext: {rtiPartner: 'TDID'}}] + uids: [{ id: 'some-random-id-value', atype: 1, ext: { rtiPartner: 'TDID' } }] }); }); it('unifiedId: ext generation with provider', function () { const userId = { - tdid: {'id': 'some-sample_id', 'ext': {'provider': 'some.provider.com'}} + tdid: { 'id': 'some-sample_id', 'ext': { 'provider': 'some.provider.com' } } }; const newEids = createEidsArray(userId); expect(newEids.length).to.equal(1); @@ -45,7 +45,7 @@ describe('Unified ID', () => { inserter: 'adserver.org', matcher: 'adserver.org', mm: 4, - uids: [{id: 'some-sample_id', atype: 1, ext: {rtiPartner: 'TDID', provider: 'some.provider.com'}}] + uids: [{ id: 'some-sample_id', atype: 1, ext: { rtiPartner: 'TDID', provider: 'some.provider.com' } }] }); }); diff --git a/test/spec/modules/uniquestAnalyticsAdapter_spec.js b/test/spec/modules/uniquestAnalyticsAdapter_spec.js index 80a573d2b0f..88120c8e59e 100644 --- a/test/spec/modules/uniquestAnalyticsAdapter_spec.js +++ b/test/spec/modules/uniquestAnalyticsAdapter_spec.js @@ -1,7 +1,7 @@ import uniquestAnalyticsAdapter from 'modules/uniquestAnalyticsAdapter.js'; -import {config} from 'src/config'; -import {EVENTS} from 'src/constants.js'; -import {server} from '../../mocks/xhr.js'; +import { config } from 'src/config'; +import { EVENTS } from 'src/constants.js'; +import { server } from '../../mocks/xhr.js'; const events = require('src/events'); diff --git a/test/spec/modules/unrulyBidAdapter_spec.js b/test/spec/modules/unrulyBidAdapter_spec.js index d73b9b6e8c7..20cf4b52708 100644 --- a/test/spec/modules/unrulyBidAdapter_spec.js +++ b/test/spec/modules/unrulyBidAdapter_spec.js @@ -1,9 +1,9 @@ /* globals describe, it, beforeEach, afterEach, sinon */ -import {expect} from 'chai' +import { expect } from 'chai' import * as utils from 'src/utils.js' -import {VIDEO, BANNER} from 'src/mediaTypes.js' -import {Renderer} from 'src/Renderer.js' -import {adapter} from 'modules/unrulyBidAdapter.js' +import { VIDEO, BANNER } from 'src/mediaTypes.js' +import { Renderer } from 'src/Renderer.js' +import { adapter } from 'modules/unrulyBidAdapter.js' describe('UnrulyAdapter', function () { function createOutStreamExchangeBid({ @@ -42,20 +42,7 @@ describe('UnrulyAdapter', function () { } } - function createOutStreamExchangeAuctionConfig() { - return { - 'seller': 'https://nexxen.tech', - 'decisionLogicURL': 'https://nexxen.tech/padecisionlogic', - 'interestGroupBuyers': 'https://mydsp.com', - 'perBuyerSignals': { - 'https://mydsp.com': { - 'floor': 'bouttreefiddy' - } - } - } - }; - - function createExchangeResponse (bidList, auctionConfigs = null) { + function createExchangeResponse (bidList) { let bids = []; if (Array.isArray(bidList)) { bids = bidList; @@ -63,18 +50,9 @@ describe('UnrulyAdapter', function () { bids.push(bidList); } - if (!auctionConfigs) { - return { - 'body': {bids} - }; - } - return { - 'body': { - bids, - auctionConfigs - } - } + 'body': { bids } + }; }; const inStreamServerResponse = { @@ -641,7 +619,7 @@ describe('UnrulyAdapter', function () { }; const getFloor = (data) => { - return {floor: 3} + return { floor: 3 } }; mockBidRequests.bids[0].getFloor = getFloor; @@ -692,231 +670,6 @@ describe('UnrulyAdapter', function () { const result = adapter.buildRequests(mockBidRequests.bids, mockBidRequests); expect(result[0].data).to.deep.equal(expectedResult); }); - describe('Protected Audience Support', function() { - it('should return an array with 2 items and enabled protected audience', function () { - mockBidRequests = { - 'bidderCode': 'unruly', - 'paapi': { - enabled: true - }, - 'bids': [ - { - 'bidder': 'unruly', - 'params': { - 'siteId': 233261, - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'mimes': [ - 'video/mp4' - ], - 'playerSize': [ - [ - 640, - 480 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '27a3ee1626a5c7', - 'bidderRequestId': '12e00d17dff07b', - 'ortb2Imp': { - 'ext': { - 'ae': 1 - } - } - }, - { - 'bidder': 'unruly', - 'params': { - 'siteId': 2234554, - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'mimes': [ - 'video/mp4' - ], - 'playerSize': [ - [ - 640, - 480 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '27a3ee1626a5c7', - 'bidderRequestId': '12e00d17dff07b', - 'ortb2Imp': { - 'ext': { - 'ae': 1 - } - } - } - ] - }; - - const result = adapter.buildRequests(mockBidRequests.bids, mockBidRequests); - expect(typeof result).to.equal('object'); - expect(result.length).to.equal(2); - expect(result[0].data.bidderRequest.bids.length).to.equal(1); - expect(result[1].data.bidderRequest.bids.length).to.equal(1); - expect(result[0].data.bidderRequest.bids[0].ortb2Imp.ext.ae).to.equal(1); - expect(result[1].data.bidderRequest.bids[0].ortb2Imp.ext.ae).to.equal(1); - }); - it('should return an array with 2 items and enabled protected audience on only one unit', function () { - mockBidRequests = { - 'bidderCode': 'unruly', - 'paapi': { - enabled: true - }, - 'bids': [ - { - 'bidder': 'unruly', - 'params': { - 'siteId': 233261, - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'mimes': [ - 'video/mp4' - ], - 'playerSize': [ - [ - 640, - 480 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '27a3ee1626a5c7', - 'bidderRequestId': '12e00d17dff07b', - 'ortb2Imp': { - 'ext': { - 'ae': 1 - } - } - }, - { - 'bidder': 'unruly', - 'params': { - 'siteId': 2234554, - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'mimes': [ - 'video/mp4' - ], - 'playerSize': [ - [ - 640, - 480 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '27a3ee1626a5c7', - 'bidderRequestId': '12e00d17dff07b', - 'ortb2Imp': { - 'ext': {} - } - } - ] - }; - - const result = adapter.buildRequests(mockBidRequests.bids, mockBidRequests); - expect(typeof result).to.equal('object'); - expect(result.length).to.equal(2); - expect(result[0].data.bidderRequest.bids.length).to.equal(1); - expect(result[1].data.bidderRequest.bids.length).to.equal(1); - expect(result[0].data.bidderRequest.bids[0].ortb2Imp.ext.ae).to.equal(1); - expect(result[1].data.bidderRequest.bids[0].ortb2Imp.ext.ae).to.be.undefined; - }); - it('disables configured protected audience when fledge is not availble', function () { - mockBidRequests = { - 'bidderCode': 'unruly', - 'fledgeEnabled': false, - 'bids': [ - { - 'bidder': 'unruly', - 'params': { - 'siteId': 233261, - }, - 'mediaTypes': { - 'video': { - 'context': 'outstream', - 'mimes': [ - 'video/mp4' - ], - 'playerSize': [ - [ - 640, - 480 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'sizes': [ - [ - 640, - 480 - ] - ], - 'bidId': '27a3ee1626a5c7', - 'bidderRequestId': '12e00d17dff07b', - 'ortb2Imp': { - 'ext': { - 'ae': 1 - } - } - } - ] - }; - - const result = adapter.buildRequests(mockBidRequests.bids, mockBidRequests); - expect(typeof result).to.equal('object'); - expect(result.length).to.equal(1); - expect(result[0].data.bidderRequest.bids.length).to.equal(1); - expect(result[0].data.bidderRequest.bids[0].ortb2Imp.ext.ae).to.be.undefined; - }); - }); }); describe('interpretResponse', function () { @@ -927,11 +680,11 @@ describe('UnrulyAdapter', function () { expect(adapter.interpretResponse()).to.deep.equal([]); }); it('should return [] when serverResponse has no bids', function () { - const mockServerResponse = {body: {bids: []}}; + const mockServerResponse = { body: { bids: [] } }; expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([]) }); it('should return array of bids when receive a successful response from server', function () { - const mockExchangeBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const mockExchangeBid = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockServerResponse = createExchangeResponse(mockExchangeBid); expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([ { @@ -967,171 +720,11 @@ describe('UnrulyAdapter', function () { ]); }); - it('should return object with an array of bids and an array of auction configs when it receives a successful response from server', function () { - const bidId = '27a3ee1626a5c7' - const mockExchangeBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); - const mockExchangeAuctionConfig = {}; - mockExchangeAuctionConfig[bidId] = createOutStreamExchangeAuctionConfig(); - const mockServerResponse = createExchangeResponse(mockExchangeBid, mockExchangeAuctionConfig); - const originalRequest = { - 'data': { - 'bidderRequest': { - 'bids': [ - { - 'bidder': 'unruly', - 'params': { - 'siteId': 233261, - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 640, - 480 - ], - [ - 640, - 480 - ], - [ - 300, - 250 - ], - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'bidId': bidId, - 'bidderRequestId': '12e00d17dff07b', - } - ] - } - } - }; - - expect(adapter.interpretResponse(mockServerResponse, originalRequest)).to.deep.equal({ - 'bids': [ - { - 'ext': { - 'statusCode': 1, - 'renderer': { - 'id': 'unruly_inarticle', - 'config': { - 'siteId': 123456, - 'targetingUUID': 'xxx-yyy-zzz' - }, - 'url': 'https://video.unrulymedia.com/native/prebid-loader.js' - }, - 'adUnitCode': 'video1' - }, - requestId: 'mockBidId', - bidderCode: 'unruly', - cpm: 20, - width: 323, - height: 323, - vastUrl: 'https://targeting.unrulymedia.com/in_article?uuid=74544e00-d43b-4f3a-a799-69d22ce979ce&supported_mime_type=application/javascript&supported_mime_type=video/mp4&tj=%7B%22site%22%3A%7B%22lang%22%3A%22en-GB%22%2C%22ref%22%3A%22%22%2C%22page%22%3A%22https%3A%2F%2Fdemo.unrulymedia.com%2FinArticle%2Finarticle_nypost_upbeat%2Ftravel_magazines.html%22%2C%22domain%22%3A%22demo.unrulymedia.com%22%7D%2C%22user%22%3A%7B%22profile%22%3A%7B%22quantcast%22%3A%7B%22segments%22%3A%5B%7B%22id%22%3A%22D%22%7D%2C%7B%22id%22%3A%22T%22%7D%5D%7D%7D%7D%7D&video_width=618&video_height=347', - netRevenue: true, - creativeId: 'mockBidId', - ttl: 360, - 'meta': { - 'mediaType': 'video', - 'videoContext': 'outstream' - }, - currency: 'USD', - renderer: fakeRenderer, - mediaType: 'video' - } - ], - 'paapi': [{ - 'bidId': bidId, - 'config': { - 'seller': 'https://nexxen.tech', - 'decisionLogicURL': 'https://nexxen.tech/padecisionlogic', - 'interestGroupBuyers': 'https://mydsp.com', - 'perBuyerSignals': { - 'https://mydsp.com': { - 'floor': 'bouttreefiddy' - } - } - } - }] - }); - }); - - it('should return object with an array of auction configs when it receives a successful response from server without bids', function () { - const bidId = '27a3ee1626a5c7'; - const mockExchangeAuctionConfig = {}; - mockExchangeAuctionConfig[bidId] = createOutStreamExchangeAuctionConfig(); - const mockServerResponse = createExchangeResponse(null, mockExchangeAuctionConfig); - const originalRequest = { - 'data': { - 'bidderRequest': { - 'bids': [ - { - 'bidder': 'unruly', - 'params': { - 'siteId': 233261, - }, - 'mediaTypes': { - 'banner': { - 'sizes': [ - [ - 640, - 480 - ], - [ - 640, - 480 - ], - [ - 300, - 250 - ], - [ - 300, - 250 - ] - ] - } - }, - 'adUnitCode': 'video2', - 'transactionId': 'a89619e3-137d-4cc5-9ed4-58a0b2a0bbc2', - 'bidId': bidId, - 'bidderRequestId': '12e00d17dff07b' - } - ] - } - } - }; - - expect(adapter.interpretResponse(mockServerResponse, originalRequest)).to.deep.equal({ - 'bids': [], - 'paapi': [{ - 'bidId': bidId, - 'config': { - 'seller': 'https://nexxen.tech', - 'decisionLogicURL': 'https://nexxen.tech/padecisionlogic', - 'interestGroupBuyers': 'https://mydsp.com', - 'perBuyerSignals': { - 'https://mydsp.com': { - 'floor': 'bouttreefiddy' - } - } - } - }] - }); - }); - it('should initialize and set the renderer', function () { expect(Renderer.install.called).to.be.false; expect(fakeRenderer.setRender.called).to.be.false; - const mockReturnedBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const mockReturnedBid = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockRenderer = { url: 'value: mockRendererURL', config: { @@ -1160,7 +753,7 @@ describe('UnrulyAdapter', function () { expect(Renderer.install.called).to.be.false; expect(fakeRenderer.setRender.called).to.be.false; - const mockReturnedBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const mockReturnedBid = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockRenderer = { url: 'value: mockRendererURL' }; @@ -1184,7 +777,7 @@ describe('UnrulyAdapter', function () { expect(Renderer.install.called).to.be.false; expect(fakeRenderer.setRender.called).to.be.false; - const mockReturnedBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const mockReturnedBid = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockRenderer = { url: 'value: mockRendererURL', config: {} @@ -1204,7 +797,7 @@ describe('UnrulyAdapter', function () { }); it('bid is placed on the bid queue when render is called', function () { - const exchangeBid = createOutStreamExchangeBid({adUnitCode: 'video', vastUrl: 'value: vastUrl'}); + const exchangeBid = createOutStreamExchangeBid({ adUnitCode: 'video', vastUrl: 'value: vastUrl' }); const exchangeResponse = createExchangeResponse(exchangeBid); adapter.interpretResponse(exchangeResponse); @@ -1224,7 +817,7 @@ describe('UnrulyAdapter', function () { }); it('should ensure that renderer is placed in Prebid supply mode', function () { - const mockExchangeBid = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const mockExchangeBid = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockServerResponse = createExchangeResponse(mockExchangeBid); expect('unruly' in window.parent).to.equal(false); @@ -1245,7 +838,7 @@ describe('UnrulyAdapter', function () { }); it('should return correct response when ad type is instream with vastXml', function () { - const mockServerResponse = {...createExchangeResponse(inStreamServerResponseWithVastXml)}; + const mockServerResponse = { ...createExchangeResponse(inStreamServerResponseWithVastXml) }; const expectedResponse = inStreamServerResponseWithVastXml; expectedResponse.mediaType = 'video'; @@ -1253,7 +846,7 @@ describe('UnrulyAdapter', function () { }); it('should return [] and log if no vastUrl in instream response', function () { - const {vastUrl, ...inStreamServerResponseNoVast} = inStreamServerResponse; + const { vastUrl, ...inStreamServerResponseNoVast } = inStreamServerResponse; const mockServerResponse = createExchangeResponse(inStreamServerResponseNoVast); expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([]); @@ -1277,7 +870,7 @@ describe('UnrulyAdapter', function () { }); it('should return [] and log if no ad in banner response', function () { - const {ad, ...bannerServerResponseNoAd} = bannerServerResponse; + const { ad, ...bannerServerResponseNoAd } = bannerServerResponse; const mockServerResponse = createExchangeResponse(bannerServerResponseNoAd); expect(adapter.interpretResponse(mockServerResponse)).to.deep.equal([]); @@ -1293,7 +886,7 @@ describe('UnrulyAdapter', function () { }); it('should return correct response for multiple bids', function () { - const outStreamServerResponse = createOutStreamExchangeBid({adUnitCode: 'video1', requestId: 'mockBidId'}); + const outStreamServerResponse = createOutStreamExchangeBid({ adUnitCode: 'video1', requestId: 'mockBidId' }); const mockServerResponse = createExchangeResponse([outStreamServerResponse, inStreamServerResponse, bannerServerResponse]); const expectedOutStreamResponse = outStreamServerResponse; expectedOutStreamResponse.mediaType = 'video'; @@ -1308,7 +901,7 @@ describe('UnrulyAdapter', function () { }); it('should return only valid bids', function () { - const {ad, ...bannerServerResponseNoAd} = bannerServerResponse; + const { ad, ...bannerServerResponseNoAd } = bannerServerResponse; const mockServerResponse = createExchangeResponse([bannerServerResponseNoAd, inStreamServerResponse]); const expectedInStreamResponse = inStreamServerResponse; expectedInStreamResponse.mediaType = 'video'; diff --git a/test/spec/modules/userId_spec.js b/test/spec/modules/userId_spec.js index 8d7c66690b0..15ed94ff962 100644 --- a/test/spec/modules/userId_spec.js +++ b/test/spec/modules/userId_spec.js @@ -14,29 +14,29 @@ import { COOKIE_SUFFIXES, HTML5_SUFFIXES, syncDelay, adUnitEidsHook, } from 'modules/userId/index.js'; -import {UID1_EIDS} from 'libraries/uid1Eids/uid1Eids.js'; -import {createEidsArray, EID_CONFIG, getEids} from 'modules/userId/eids.js'; -import {config} from 'src/config.js'; +import { UID1_EIDS } from 'libraries/uid1Eids/uid1Eids.js'; +import { createEidsArray, EID_CONFIG, getEids } from 'modules/userId/eids.js'; +import { config } from 'src/config.js'; import * as utils from 'src/utils.js'; import * as events from 'src/events.js'; -import {EVENTS} from 'src/constants.js'; -import {getGlobal} from 'src/prebidGlobal.js'; -import {resetConsentData, } from 'modules/consentManagementTcf.js'; -import {setEventFiredFlag as liveIntentIdSubmoduleDoNotFireEvent} from '../../../libraries/liveIntentId/idSystem.js'; -import {sharedIdSystemSubmodule} from 'modules/sharedIdSystem.js'; -import {pubProvidedIdSubmodule} from 'modules/pubProvidedIdSystem.js'; +import { EVENTS } from 'src/constants.js'; +import { getGlobal } from 'src/prebidGlobal.js'; +import { resetConsentData, } from 'modules/consentManagementTcf.js'; +import { setEventFiredFlag as liveIntentIdSubmoduleDoNotFireEvent } from '../../../libraries/liveIntentId/idSystem.js'; +import { sharedIdSystemSubmodule } from 'modules/sharedIdSystem.js'; +import { pubProvidedIdSubmodule } from 'modules/pubProvidedIdSystem.js'; import * as mockGpt from '../integration/faker/googletag.js'; -import {requestBids, startAuction} from 'src/prebid.js'; -import {hook} from '../../../src/hook.js'; -import {mockGdprConsent} from '../../helpers/consentData.js'; -import {getPPID} from '../../../src/adserver.js'; -import {uninstall as uninstallTcfControl} from 'modules/tcfControl.js'; -import {allConsent, GDPR_GVLIDS, gdprDataHandler} from '../../../src/consentHandler.js'; -import {MODULE_TYPE_UID} from '../../../src/activities/modules.js'; -import {ACTIVITY_ENRICH_EIDS} from '../../../src/activities/activities.js'; -import {ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE} from '../../../src/activities/params.js'; -import {extractEids} from '../../../modules/prebidServerBidAdapter/bidderConfig.js'; -import {generateSubmoduleContainers, addIdData } from '../../../modules/userId/index.js'; +import { requestBids, startAuction } from 'src/prebid.js'; +import { hook } from '../../../src/hook.js'; +import { mockGdprConsent } from '../../helpers/consentData.js'; +import { getPPID } from '../../../src/adserver.js'; +import { uninstall as uninstallTcfControl } from 'modules/tcfControl.js'; +import { allConsent, GDPR_GVLIDS, gdprDataHandler } from '../../../src/consentHandler.js'; +import { MODULE_TYPE_UID } from '../../../src/activities/modules.js'; +import { ACTIVITY_ENRICH_EIDS } from '../../../src/activities/activities.js'; +import { ACTIVITY_PARAM_COMPONENT_NAME, ACTIVITY_PARAM_COMPONENT_TYPE } from '../../../src/activities/params.js'; +import { extractEids } from '../../../modules/prebidServerBidAdapter/bidderConfig.js'; +import { generateSubmoduleContainers, addIdData } from '../../../modules/userId/index.js'; import { registerActivityControl } from '../../../src/activities/rules.js'; import { discloseStorageUse, @@ -62,12 +62,12 @@ describe('User ID', function () { } function getStorageMock(name = 'pubCommonId', key = 'pubcid', type = 'cookie', expires = 30, refreshInSeconds) { - return {name: name, storage: {name: key, type: type, expires: expires, refreshInSeconds: refreshInSeconds}} + return { name: name, storage: { name: key, type: type, expires: expires, refreshInSeconds: refreshInSeconds } } } function getConfigValueMock(name, value) { return { - userSync: {syncDelay: 0, userIds: [{name: name, value: value}]} + userSync: { syncDelay: 0, userIds: [{ name: name, value: value }] } } } @@ -108,9 +108,9 @@ describe('User ID', function () { function getAdUnitMock(code = 'adUnit-code') { return { code, - mediaTypes: {banner: {}, native: {}}, + mediaTypes: { banner: {}, native: {} }, sizes: [[300, 200], [300, 600]], - bids: [{bidder: 'sampleBidder', params: {placementId: 'banner-only-bidder'}}, {bidder: 'anotherSampleBidder', params: {placementId: 'banner-only-bidder'}}] + bids: [{ bidder: 'sampleBidder', params: { placementId: 'banner-only-bidder' } }, { bidder: 'anotherSampleBidder', params: { placementId: 'banner-only-bidder' } }] }; } @@ -147,7 +147,7 @@ describe('User ID', function () { function runBidsHook(...args) { startDelay = delay(); - const result = startAuctionHook(...args, {mkDelay: startDelay}); + const result = startAuctionHook(...args, { mkDelay: startDelay }); return new Promise((resolve) => setTimeout(() => resolve(result))); } @@ -160,7 +160,7 @@ describe('User ID', function () { function initModule(config) { callbackDelay = delay(); - return init(config, {mkDelay: callbackDelay}); + return init(config, { mkDelay: callbackDelay }); } before(function () { @@ -181,7 +181,7 @@ describe('User ID', function () { afterEach(() => { sandbox.restore(); config.resetConfig(); - startAuction.getHooks({hook: startAuctionHook}).remove(); + startAuction.getHooks({ hook: startAuctionHook }).remove(); }); after(() => { @@ -197,7 +197,7 @@ describe('User ID', function () { }); it('are registered when ID submodule is registered', () => { - attachIdSystem({name: 'gvlidMock', gvlid: 123}); + attachIdSystem({ name: 'gvlidMock', gvlid: 123 }); sinon.assert.calledWith(GDPR_GVLIDS.register, MODULE_TYPE_UID, 'gvlidMock', 123); }) }) @@ -221,10 +221,10 @@ describe('User ID', function () { Object.entries({ 'not an object': 'garbage', 'missing name': {}, - 'empty name': {name: ''}, - 'empty storage config': {name: 'mockId', storage: {}}, - 'storage type, but no storage name': mockConfig({name: ''}), - 'storage name, but no storage type': mockConfig({type: undefined}), + 'empty name': { name: '' }, + 'empty storage config': { name: 'mockId', storage: {} }, + 'storage type, but no storage name': mockConfig({ name: '' }), + 'storage name, but no storage type': mockConfig({ type: undefined }), }).forEach(([t, config]) => { it(`should log a warning and reject configuration with ${t}`, () => { expect(getValidSubmoduleConfigs([config]).length).to.equal(0); @@ -245,11 +245,11 @@ describe('User ID', function () { ['refreshInSeconds', 'expires'].forEach(param => { describe(`${param} parameter`, () => { it('should be made a number, when possible', () => { - expect(getValidSubmoduleConfigs([mockConfig({[param]: '123'})])[0].storage[param]).to.equal(123); + expect(getValidSubmoduleConfigs([mockConfig({ [param]: '123' })])[0].storage[param]).to.equal(123); }); it('should log a warning when not a number', () => { - expect(getValidSubmoduleConfigs([mockConfig({[param]: 'garbage'})])[0].storage[param]).to.not.exist; + expect(getValidSubmoduleConfigs([mockConfig({ [param]: 'garbage' })])[0].storage[param]).to.not.exist; sinon.assert.called(utils.logWarn) }); @@ -286,8 +286,8 @@ describe('User ID', function () { }); function getGlobalEids() { - const ortb2Fragments = {global: {}}; - return expectImmediateBidHook(sinon.stub(), {ortb2Fragments}).then(() => ortb2Fragments.global.user?.ext?.eids); + const ortb2Fragments = { global: {} }; + return expectImmediateBidHook(sinon.stub(), { ortb2Fragments }).then(() => ortb2Fragments.global.user?.ext?.eids); } it('Check same cookie behavior', async function () { @@ -303,7 +303,7 @@ describe('User ID', function () { expect(eids1).to.eql([ { source: 'pubcid.org', - uids: [{id: pubcid, atype: 1}] + uids: [{ id: pubcid, atype: 1 }] } ]) const eids2 = await getGlobalEids(); @@ -324,7 +324,7 @@ describe('User ID', function () { coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); // erase cookie expect(eids1).to.eql([{ source: 'pubcid.org', - uids: [{id: pubcid1, atype: 1}] + uids: [{ id: pubcid1, atype: 1 }] }]) init(config); @@ -335,7 +335,7 @@ describe('User ID', function () { pubcid2 = coreStorage.getCookie('pubcid'); // get second cookie expect(eids2).to.eql([{ source: 'pubcid.org', - uids: [{id: pubcid2, atype: 1}] + uids: [{ id: pubcid2, atype: 1 }] }]) expect(pubcid1).to.not.equal(pubcid2); }); @@ -348,13 +348,13 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'altpubcid200000', atype: 1}] + uids: [{ id: 'altpubcid200000', atype: 1 }] }]) }); it('Extend cookie', async function () { let customConfig = getConfigMock(['pubCommonId', 'pubcid_alt', 'cookie']); - customConfig = addConfig(customConfig, 'params', {extend: true}); + customConfig = addConfig(customConfig, 'params', { extend: true }); init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); @@ -364,13 +364,13 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.deep.equal([{ source: 'pubcid.org', - uids: [{id: 'altpubcid200000', atype: 1}] + uids: [{ id: 'altpubcid200000', atype: 1 }] }]); }); it('Disable auto create', async function () { let customConfig = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customConfig = addConfig(customConfig, 'params', {create: false}); + customConfig = addConfig(customConfig, 'params', { create: false }); init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); @@ -385,28 +385,28 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ createMockIdSubmodule('mockId1', null, null, - {'mockId1': {source: 'mock1source', atype: 1}}), + { 'mockId1': { source: 'mock1source', atype: 1 } }), createMockIdSubmodule('mockId2v1', null, null, - {'mockId2v1': {source: 'mock2source', atype: 2, getEidExt: () => ({v: 1})}}), + { 'mockId2v1': { source: 'mock2source', atype: 2, getEidExt: () => ({ v: 1 }) } }), createMockIdSubmodule('mockId2v2', null, null, - {'mockId2v2': {source: 'mock2source', atype: 2, getEidExt: () => ({v: 2})}}), + { 'mockId2v2': { source: 'mock2source', atype: 2, getEidExt: () => ({ v: 2 }) } }), createMockIdSubmodule('mockId2v3', null, null, { 'mockId2v3'(ids) { return { source: 'mock2source', inserter: 'ins', - ext: {v: 2}, - uids: ids.map(id => ({id, atype: 2})) + ext: { v: 2 }, + uids: ids.map(id => ({ id, atype: 2 })) } } }), createMockIdSubmodule('mockId2v4', null, null, { 'mockId2v4'(ids) { return ids.map(id => ({ - uids: [{id, atype: 0}], + uids: [{ id, atype: 0 }], source: 'mock2source', inserter: 'ins', - ext: {v: 2} + ext: { v: 2 } })) } }) @@ -428,7 +428,7 @@ describe('User ID', function () { it('should not alter values returned by adapters', () => { let eid = { source: 'someid.org', - uids: [{id: 'id-1'}] + uids: [{ id: 'id-1' }] }; const config = new Map([ ['someId', function () { @@ -439,7 +439,7 @@ describe('User ID', function () { someId: 'id-1', pubProvidedId: [{ source: 'someid.org', - uids: [{id: 'id-2'}] + uids: [{ id: 'id-2' }] }], } createEidsArray(userid, config); @@ -447,10 +447,10 @@ describe('User ID', function () { expect(allEids).to.eql([ { source: 'someid.org', - uids: [{id: 'id-1'}, {id: 'id-2'}] + uids: [{ id: 'id-1' }, { id: 'id-2' }] } ]) - expect(eid.uids).to.eql([{'id': 'id-1'}]) + expect(eid.uids).to.eql([{ 'id': 'id-1' }]) }); it('should filter out entire EID if none of the uids are strings', () => { @@ -516,7 +516,7 @@ describe('User ID', function () { { source: 'mock2source', inserter: 'ins', - ext: {v: 2}, + ext: { v: 2 }, uids: [ { id: 'mock-2-1', @@ -553,7 +553,7 @@ describe('User ID', function () { atype: 0 } ], - ext: {v: 2} + ext: { v: 2 } }]) }) it('when merging with pubCommonId, should not alter its eids', () => { @@ -562,7 +562,7 @@ describe('User ID', function () { { source: 'mock1Source', uids: [ - {id: 'uid2'} + { id: 'uid2' } ] } ], @@ -571,7 +571,7 @@ describe('User ID', function () { const eids = createEidsArray(uid); expect(eids).to.have.length(1); expect(eids[0].uids.map(u => u.id)).to.have.members(['uid1', 'uid2']); - expect(uid.pubProvidedId[0].uids).to.eql([{id: 'uid2'}]); + expect(uid.pubProvidedId[0].uids).to.eql([{ id: 'uid2' }]); }); }) @@ -579,7 +579,7 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); - const ids = {pubcid: '11111'}; + const ids = { pubcid: '11111' }; config.setConfig({ userSync: { auctionDelay: 10, // with auctionDelay > 0, no auction is needed to complete init @@ -599,10 +599,10 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {mockId1: 'mockId1_value'}}), - createMockIdSubmodule('mockId2Module', {id: {mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module'}}), - createMockIdSubmodule('mockId3Module', {id: {mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module'}}), - createMockIdSubmodule('mockId4Module', {id: {mockId4: 'mockId4_value'}}) + createMockIdSubmodule('mockId1Module', { id: { mockId1: 'mockId1_value' } }), + createMockIdSubmodule('mockId2Module', { id: { mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module' } }), + createMockIdSubmodule('mockId3Module', { id: { mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module' } }), + createMockIdSubmodule('mockId4Module', { id: { mockId4: 'mockId4_value' } }) ]); config.setConfig({ @@ -633,10 +633,10 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {mockId1: 'mockId1_value'}}), - createMockIdSubmodule('mockId2Module', {id: {mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module'}}, 'mockId2Module_alias'), - createMockIdSubmodule('mockId3Module', {id: {mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module'}}, 'mockId3Module_alias'), - createMockIdSubmodule('mockId4Module', {id: {mockId4: 'mockId4_value'}}) + createMockIdSubmodule('mockId1Module', { id: { mockId1: 'mockId1_value' } }), + createMockIdSubmodule('mockId2Module', { id: { mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module' } }, 'mockId2Module_alias'), + createMockIdSubmodule('mockId3Module', { id: { mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module' } }, 'mockId3Module_alias'), + createMockIdSubmodule('mockId4Module', { id: { mockId4: 'mockId4_value' } }) ]); config.setConfig({ @@ -667,8 +667,8 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {mockId1: 'mockId1_value', mockId2: 'mockId2_value_from_mockId1Module'}}), - createMockIdSubmodule('mockId2Module', {id: {mockId1: 'mockId1_value_from_mockId2Module', mockId2: 'mockId2_value'}}), + createMockIdSubmodule('mockId1Module', { id: { mockId1: 'mockId1_value', mockId2: 'mockId2_value_from_mockId1Module' } }), + createMockIdSubmodule('mockId2Module', { id: { mockId1: 'mockId1_value_from_mockId2Module', mockId2: 'mockId2_value' } }), ]); config.setConfig({ @@ -698,10 +698,10 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {mockId1: 'mockId1_value'}}), - createMockIdSubmodule('mockId2Module', {id: {mockId2: 'mockId2_value'}}), - createMockIdSubmodule('mockId3Module', {id: undefined}), - createMockIdSubmodule('mockId4Module', {id: {mockId4: 'mockId4_value'}}) + createMockIdSubmodule('mockId1Module', { id: { mockId1: 'mockId1_value' } }), + createMockIdSubmodule('mockId2Module', { id: { mockId2: 'mockId2_value' } }), + createMockIdSubmodule('mockId3Module', { id: undefined }), + createMockIdSubmodule('mockId4Module', { id: { mockId4: 'mockId4_value' } }) ]); config.setConfig({ @@ -732,7 +732,7 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); - const ids = {'pubcid': '11111'}; + const ids = { 'pubcid': '11111' }; config.setConfig({ userSync: { auctionDelay: 10, @@ -755,7 +755,7 @@ describe('User ID', function () { })]); const moduleConfig = { name: 'mockId', - value: {mockId: 'mockIdValue'}, + value: { mockId: 'mockIdValue' }, some: 'config' }; config.setConfig({ @@ -771,10 +771,10 @@ describe('User ID', function () { it('pbjs.getUserIdsAsEids should prioritize user ids according to config available to core', () => { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {uid2: {id: 'uid2_value'}}}, null, createMockEid('uid2')), - createMockIdSubmodule('mockId2Module', {id: {pubcid: 'pubcid_value', lipb: {lipbid: 'lipbid_value_from_mockId2Module'}}}, null, createMockEid('pubcid')), - createMockIdSubmodule('mockId3Module', {id: {uid2: {id: 'uid2_value_from_mockId3Module'}, pubcid: 'pubcid_value_from_mockId3Module', lipb: {lipbid: 'lipbid_value'}, merkleId: {id: 'merkleId_value_from_mockId3Module'}}}, null, {...createMockEid('uid2'), ...createMockEid('merkleId'), ...createMockEid('lipb')}), - createMockIdSubmodule('mockId4Module', {id: {merkleId: {id: 'merkleId_value'}}}, null, createMockEid('merkleId')) + createMockIdSubmodule('mockId1Module', { id: { uid2: { id: 'uid2_value' } } }, null, createMockEid('uid2')), + createMockIdSubmodule('mockId2Module', { id: { pubcid: 'pubcid_value', lipb: { lipbid: 'lipbid_value_from_mockId2Module' } } }, null, createMockEid('pubcid')), + createMockIdSubmodule('mockId3Module', { id: { uid2: { id: 'uid2_value_from_mockId3Module' }, pubcid: 'pubcid_value_from_mockId3Module', lipb: { lipbid: 'lipbid_value' }, merkleId: { id: 'merkleId_value_from_mockId3Module' } } }, null, { ...createMockEid('uid2'), ...createMockEid('merkleId'), ...createMockEid('lipb') }), + createMockIdSubmodule('mockId4Module', { id: { merkleId: { id: 'merkleId_value' } } }, null, createMockEid('merkleId')) ]); config.setConfig({ userSync: { @@ -809,9 +809,9 @@ describe('User ID', function () { it('pbjs.getUserIdsAsEids should prioritize the uid1 according to config available to core', () => { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {tdid: {id: 'uid1_value'}}}, null, UID1_EIDS), - createMockIdSubmodule('mockId2Module', {id: {tdid: {id: 'uid1Id_value_from_mockId2Module'}}}, null, UID1_EIDS), - createMockIdSubmodule('mockId3Module', {id: {tdid: {id: 'uid1Id_value_from_mockId3Module'}}}, null, UID1_EIDS) + createMockIdSubmodule('mockId1Module', { id: { tdid: { id: 'uid1_value' } } }, null, UID1_EIDS), + createMockIdSubmodule('mockId2Module', { id: { tdid: { id: 'uid1Id_value_from_mockId2Module' } } }, null, UID1_EIDS), + createMockIdSubmodule('mockId3Module', { id: { tdid: { id: 'uid1Id_value_from_mockId3Module' } } }, null, UID1_EIDS) ]); config.setConfig({ userSync: { @@ -853,11 +853,11 @@ describe('User ID', function () { it('should merge together submodules\' eid configs', () => { setSubmoduleRegistry([ - mockSubmod('mock1', {mock1: {m: 1}}), - mockSubmod('mock2', {mock2: {m: 2}}) + mockSubmod('mock1', { mock1: { m: 1 } }), + mockSubmod('mock2', { mock2: { m: 2 } }) ]); - expect(EID_CONFIG.get('mock1')).to.eql({m: 1}); - expect(EID_CONFIG.get('mock2')).to.eql({m: 2}); + expect(EID_CONFIG.get('mock1')).to.eql({ m: 1 }); + expect(EID_CONFIG.get('mock2')).to.eql({ m: 2 }); }); it('should respect idPriority', () => { @@ -874,11 +874,11 @@ describe('User ID', function () { } }); setSubmoduleRegistry([ - mockSubmod('mod1', {m1: {i: 1}, m2: {i: 2}}), - mockSubmod('mod2', {m1: {i: 3}, m2: {i: 4}}) + mockSubmod('mod1', { m1: { i: 1 }, m2: { i: 2 } }), + mockSubmod('mod2', { m1: { i: 3 }, m2: { i: 4 } }) ]); - expect(EID_CONFIG.get('m1')).to.eql({i: 3}); - expect(EID_CONFIG.get('m2')).to.eql({i: 2}); + expect(EID_CONFIG.get('m1')).to.eql({ i: 3 }); + expect(EID_CONFIG.get('m2')).to.eql({ i: 2 }); }); }) @@ -894,11 +894,11 @@ describe('User ID', function () { userSync: { ppid: 'pubcid.org', userIds: [ - { name: 'pubCommonId', value: {'pubcid': 'pubCommon-id-value-pubCommon-id-value'} }, + { name: 'pubCommonId', value: { 'pubcid': 'pubCommon-id-value-pubCommon-id-value' } }, ] } }); - return expectImmediateBidHook(() => {}, {adUnits}).then(() => { + return expectImmediateBidHook(() => {}, { adUnits }).then(() => { // ppid should have been set without dashes and stuff expect(window.googletag._ppid).to.equal('pubCommonidvaluepubCommonidvalue'); }); @@ -909,8 +909,8 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ // some of the ids are padded to have length >= 32 characters - createMockIdSubmodule('mockId1Module', {id: {uid2: {id: 'uid2_value_7ac66c0f148de9519b8bd264312c4d64'}}}), - createMockIdSubmodule('mockId2Module', {id: {pubcid: 'pubcid_value_7ac66c0f148de9519b8bd264312c4d64', lipb: {lipbid: 'lipbid_value_from_mockId2Module_7ac66c0f148de9519b8bd264312c4d64'}}}), + createMockIdSubmodule('mockId1Module', { id: { uid2: { id: 'uid2_value_7ac66c0f148de9519b8bd264312c4d64' } } }), + createMockIdSubmodule('mockId2Module', { id: { pubcid: 'pubcid_value_7ac66c0f148de9519b8bd264312c4d64', lipb: { lipbid: 'lipbid_value_from_mockId2Module_7ac66c0f148de9519b8bd264312c4d64' } } }), createMockIdSubmodule('mockId3Module', { id: { uid2: { @@ -930,7 +930,7 @@ describe('User ID', function () { getValue(data) { return data.id } } }), - createMockIdSubmodule('mockId4Module', {id: {merkleId: {id: 'merkleId_value_7ac66c0f148de9519b8bd264312c4d64'}}}) + createMockIdSubmodule('mockId4Module', { id: { merkleId: { id: 'merkleId_value_7ac66c0f148de9519b8bd264312c4d64' } } }) ]); // before ppid should not be set @@ -952,7 +952,7 @@ describe('User ID', function () { } }); - return expectImmediateBidHook(() => {}, {adUnits}).then(() => { + return expectImmediateBidHook(() => {}, { adUnits }).then(() => { expect(window.googletag._ppid).to.equal('uid2valuefrommockId3Module7ac66c0f148de9519b8bd264312c4d64'); }); }); @@ -1016,7 +1016,7 @@ describe('User ID', function () { setSubmoduleRegistry([{ name: 'sharedId', getId: function () { - return {callback} + return { callback } }, decode(d) { return d @@ -1038,10 +1038,10 @@ describe('User ID', function () { ] } }); - return expectImmediateBidHook(() => {}, {adUnits}).then(() => { + return expectImmediateBidHook(() => {}, { adUnits }).then(() => { expect(window.googletag._ppid).to.be.undefined; const uid = 'thismustbelongerthan32characters' - callback.yield({pubcid: uid}); + callback.yield({ pubcid: uid }); expect(window.googletag._ppid).to.equal(uid); }); }); @@ -1056,13 +1056,13 @@ describe('User ID', function () { userSync: { ppid: 'pubcid.org', userIds: [ - { name: 'pubCommonId', value: {'pubcid': 'pubcommonIdValue'} }, + { name: 'pubCommonId', value: { 'pubcid': 'pubcommonIdValue' } }, ] } }); // before ppid should not be set expect(window.googletag._ppid).to.equal(undefined); - return expectImmediateBidHook(() => {}, {adUnits}).then(() => { + return expectImmediateBidHook(() => {}, { adUnits }).then(() => { // ppid should NOT have been set expect(window.googletag._ppid).to.equal(undefined); // a warning should have been emmited @@ -1078,7 +1078,7 @@ describe('User ID', function () { userSync: { ppid: 'pubcid.org', userIds: [ - { name: 'pubCommonId', value: {'pubcid': id} }, + { name: 'pubCommonId', value: { 'pubcid': id } }, ] } }); @@ -1091,8 +1091,8 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ // some of the ids are padded to have length >= 32 characters - createMockIdSubmodule('mockId1Module', {id: {uid2: {id: 'uid2_value_7ac66c0f148de9519b8bd264312c4d64'}}}), - createMockIdSubmodule('mockId2Module', {id: {pubcid: 'pubcid_value_7ac66c0f148de9519b8bd264312c4d64', lipb: {lipbid: 'lipbid_value_from_mockId2Module_7ac66c0f148de9519b8bd264312c4d64'}}}), + createMockIdSubmodule('mockId1Module', { id: { uid2: { id: 'uid2_value_7ac66c0f148de9519b8bd264312c4d64' } } }), + createMockIdSubmodule('mockId2Module', { id: { pubcid: 'pubcid_value_7ac66c0f148de9519b8bd264312c4d64', lipb: { lipbid: 'lipbid_value_from_mockId2Module_7ac66c0f148de9519b8bd264312c4d64' } } }), createMockIdSubmodule('mockId3Module', { id: { uid2: { @@ -1112,7 +1112,7 @@ describe('User ID', function () { getValue(data) { return data.id } } }), - createMockIdSubmodule('mockId4Module', {id: {merkleId: {id: 'merkleId_value_7ac66c0f148de9519b8bd264312c4d64'}}}) + createMockIdSubmodule('mockId4Module', { id: { merkleId: { id: 'merkleId_value_7ac66c0f148de9519b8bd264312c4d64' } } }) ]); // before ppid should not be set @@ -1140,7 +1140,7 @@ describe('User ID', function () { }); describe('refreshing before init is complete', () => { - const MOCK_ID = {'MOCKID': '1111'}; + const MOCK_ID = { 'MOCKID': '1111' }; let mockIdCallback; let startInit; @@ -1154,7 +1154,7 @@ describe('User ID', function () { 'mid': value['MOCKID'] }; }, - getId: sinon.stub().returns({callback: mockIdCallback}) + getId: sinon.stub().returns({ callback: mockIdCallback }) }; init(config); setSubmoduleRegistry([mockIdSystem]); @@ -1163,7 +1163,7 @@ describe('User ID', function () { auctionDelay: 10, userIds: [{ name: 'mockId', - storage: {name: 'MOCKID', type: 'cookie'} + storage: { name: 'MOCKID', type: 'cookie' } }] } }); @@ -1190,11 +1190,11 @@ describe('User ID', function () { startInit(); startAuctionHook(() => { done(); - }, {adUnits: [getAdUnitMock()]}, {delay: delay()}); + }, { adUnits: [getAdUnitMock()] }, { delay: delay() }); getGlobal().refreshUserIds(); clearStack().then(() => { // simulate init complete - mockIdCallback.callArg(0, {id: {MOCKID: '1111'}}); + mockIdCallback.callArg(0, { id: { MOCKID: '1111' } }); }); }); @@ -1203,7 +1203,7 @@ describe('User ID', function () { startAuctionHook(() => { done(); }, - {adUnits: [getAdUnitMock()]}, + { adUnits: [getAdUnitMock()] }, { delay: delay(), getIds: () => Promise.reject(new Error()) @@ -1230,7 +1230,7 @@ describe('User ID', function () { [name]: value }; }, - getId: sinon.stub().callsFake(() => ({id: name})) + getId: sinon.stub().callsFake(() => ({ id: name })) }; } let id1, id2; @@ -1244,10 +1244,10 @@ describe('User ID', function () { auctionDelay: 10, userIds: [{ name: 'mock1', - storage: {name: 'mock1', type: 'cookie'} + storage: { name: 'mock1', type: 'cookie' } }, { name: 'mock2', - storage: {name: 'mock2', type: 'cookie'} + storage: { name: 'mock2', type: 'cookie' } }] } }) @@ -1259,7 +1259,7 @@ describe('User ID', function () { 'in init': () => id1.getId.callsFake(() => { throw new Error() }), 'in callback': () => { const mockCallback = sinon.stub().callsFake(() => { throw new Error() }); - id1.getId.callsFake(() => ({callback: mockCallback})) + id1.getId.callsFake(() => ({ callback: mockCallback })) } }).forEach(([t, setup]) => { describe(`${t}`, () => { @@ -1274,7 +1274,7 @@ describe('User ID', function () { }); it('pbjs.refreshUserIds updates submodules', function(done) { const sandbox = sinon.createSandbox(); - const mockIdCallback = sandbox.stub().returns({id: {'MOCKID': '1111'}}); + const mockIdCallback = sandbox.stub().returns({ id: { 'MOCKID': '1111' } }); const mockIdSystem = { name: 'mockId', decode: function(value) { @@ -1292,7 +1292,7 @@ describe('User ID', function () { auctionDelay: 10, userIds: [{ name: 'mockId', - value: {id: {mockId: '1111'}} + value: { id: { mockId: '1111' } } }] } }); @@ -1305,7 +1305,7 @@ describe('User ID', function () { auctionDelay: 10, userIds: [{ name: 'mockId', - value: {id: {mockId: '1212'}} + value: { id: { mockId: '1212' } } }] } }); @@ -1320,10 +1320,10 @@ describe('User ID', function () { init(config); setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {mockId1: 'mockId1_value'}}), - createMockIdSubmodule('mockId2Module', {id: {mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module'}}), - createMockIdSubmodule('mockId3Module', {id: {mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module'}}), - createMockIdSubmodule('mockId4Module', {id: {mockId4: 'mockId4_value'}}) + createMockIdSubmodule('mockId1Module', { id: { mockId1: 'mockId1_value' } }), + createMockIdSubmodule('mockId2Module', { id: { mockId2: 'mockId2_value', mockId3: 'mockId3_value_from_mockId2Module' } }), + createMockIdSubmodule('mockId3Module', { id: { mockId1: 'mockId1_value_from_mockId3Module', mockId2: 'mockId2_value_from_mockId3Module', mockId3: 'mockId3_value', mockId4: 'mockId4_value_from_mockId3Module' } }), + createMockIdSubmodule('mockId4Module', { id: { mockId4: 'mockId4_value' } }) ]); config.setConfig({ @@ -1378,7 +1378,7 @@ describe('User ID', function () { coreStorage.setCookie('refreshedid', '', EXPIRED_COOKIE_DATE); const sandbox = sinon.createSandbox(); - const mockIdCallback = sandbox.stub().returns({id: {'MOCKID': '1111'}}); + const mockIdCallback = sandbox.stub().returns({ id: { 'MOCKID': '1111' } }); const refreshUserIdsCallback = sandbox.stub(); const mockIdSystem = { @@ -1391,7 +1391,7 @@ describe('User ID', function () { getId: mockIdCallback }; - const refreshedIdCallback = sandbox.stub().returns({id: {'REFRESH': '1111'}}); + const refreshedIdCallback = sandbox.stub().returns({ id: { 'REFRESH': '1111' } }); const refreshedIdSystem = { name: 'refreshedId', @@ -1412,17 +1412,17 @@ describe('User ID', function () { userIds: [ { name: 'mockId', - storage: {name: 'MOCKID', type: 'cookie'}, + storage: { name: 'MOCKID', type: 'cookie' }, }, { name: 'refreshedId', - storage: {name: 'refreshedid', type: 'cookie'}, + storage: { name: 'refreshedid', type: 'cookie' }, } ] } }); - return getGlobal().refreshUserIds({submoduleNames: 'refreshedId'}, refreshUserIdsCallback).then(() => { + return getGlobal().refreshUserIds({ submoduleNames: 'refreshedId' }, refreshUserIdsCallback).then(() => { expect(refreshedIdCallback.callCount).to.equal(2); expect(mockIdCallback.callCount).to.equal(1); expect(refreshUserIdsCallback.callCount).to.equal(1); @@ -1486,7 +1486,7 @@ describe('User ID', function () { it('handles config with empty usersync object', function () { init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); - config.setConfig({userSync: {}}); + config.setConfig({ userSync: {} }); expect(typeof utils.logInfo.args[0]).to.equal('undefined'); }); @@ -1508,10 +1508,10 @@ describe('User ID', function () { userSync: { userIds: [{ name: '', - value: {test: '1'} + value: { test: '1' } }, { name: 'foo', - value: {test: '1'} + value: { test: '1' } }] } }); @@ -1547,10 +1547,10 @@ describe('User ID', function () { userSync: { syncDelay: 0, userIds: [{ - name: 'pubCommonId', value: {'pubcid': '11111'} + name: 'pubCommonId', value: { 'pubcid': '11111' } }, { name: 'pubProvidedId', - storage: {name: 'pubProvidedId', type: 'cookie'} + storage: { name: 'pubProvidedId', type: 'cookie' } }] } }); @@ -1565,7 +1565,7 @@ describe('User ID', function () { syncDelay: 99, userIds: [{ name: 'pubCommonId', - storage: {name: 'pubCommonId', type: 'cookie'} + storage: { name: 'pubCommonId', type: 'cookie' } }] } }); @@ -1580,7 +1580,7 @@ describe('User ID', function () { auctionDelay: 100, userIds: [{ name: 'pubCommonId', - storage: {name: 'pubCommonId', type: 'cookie'} + storage: { name: 'pubCommonId', type: 'cookie' } }] } }); @@ -1595,7 +1595,7 @@ describe('User ID', function () { auctionDelay: '', userIds: [{ name: 'pubCommonId', - storage: {name: 'pubCommonId', type: 'cookie'} + storage: { name: 'pubCommonId', type: 'cookie' } }] } }); @@ -1630,9 +1630,9 @@ describe('User ID', function () { getId: function () { const storedId = coreStorage.getCookie('MOCKID'); if (storedId) { - return {id: {'MOCKID': storedId}}; + return { id: { 'MOCKID': storedId } }; } - return {callback: mockIdCallback}; + return { callback: mockIdCallback }; } }; initModule(config); @@ -1652,12 +1652,12 @@ describe('User ID', function () { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); - return runBidsHook(auctionSpy, {adUnits}).then(() => { + return runBidsHook(auctionSpy, { adUnits }).then(() => { // check auction was delayed startDelay.calledWith(33); auctionSpy.calledOnce.should.equal(false); @@ -1671,7 +1671,7 @@ describe('User ID', function () { auctionSpy.calledOnce.should.equal(true); // does not call auction again once ids are synced - mockIdCallback.callArgWith(0, {'MOCKID': '1234'}); + mockIdCallback.callArgWith(0, { 'MOCKID': '1234' }); auctionSpy.calledOnce.should.equal(true); // no sync after auction ends @@ -1685,12 +1685,12 @@ describe('User ID', function () { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); - return runBidsHook(auctionSpy, {adUnits}).then(() => { + return runBidsHook(auctionSpy, { adUnits }).then(() => { // check auction was delayed startDelay.calledWith(33); auctionSpy.calledOnce.should.equal(false); @@ -1699,7 +1699,7 @@ describe('User ID', function () { mockIdCallback.calledOnce.should.equal(true); // if ids returned, should continue auction - mockIdCallback.callArgWith(0, {'MOCKID': '1234'}); + mockIdCallback.callArgWith(0, { 'MOCKID': '1234' }); return clearStack(); }).then(() => { auctionSpy.calledOnce.should.equal(true); @@ -1722,12 +1722,12 @@ describe('User ID', function () { auctionDelay: 0, syncDelay: 77, userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); - return expectImmediateBidHook(auctionSpy, {adUnits}) + return expectImmediateBidHook(auctionSpy, { adUnits }) .then(() => { // should not delay auction auctionSpy.calledOnce.should.equal(true); @@ -1755,12 +1755,12 @@ describe('User ID', function () { auctionDelay: 0, syncDelay: 0, userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); - return expectImmediateBidHook(auctionSpy, {adUnits}) + return expectImmediateBidHook(auctionSpy, { adUnits }) .then(() => { // auction should not be delayed auctionSpy.calledOnce.should.equal(true); @@ -1786,12 +1786,12 @@ describe('User ID', function () { auctionDelay: 33, syncDelay: 77, userIds: [{ - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); - return runBidsHook(auctionSpy, {adUnits}).then(() => { + return runBidsHook(auctionSpy, { adUnits }).then(() => { auctionSpy.calledOnce.should.equal(true); mockIdCallback.calledOnce.should.equal(false); @@ -1810,9 +1810,9 @@ describe('User ID', function () { function getGlobalEids() { return new Promise((resolve) => { - startAuctionHook(function ({ortb2Fragments}) { + startAuctionHook(function ({ ortb2Fragments }) { resolve(ortb2Fragments.global.user?.ext?.eids); - }, {ortb2Fragments: { global: {} }}) + }, { ortb2Fragments: { global: {} } }) }) } @@ -1826,7 +1826,7 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] + uids: [{ id: 'testpubcid', atype: 1 }] }]) } finally { coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1846,7 +1846,7 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] + uids: [{ id: 'testpubcid', atype: 1 }] }]); } finally { localStorage.removeItem('pubcid'); @@ -1868,7 +1868,7 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] + uids: [{ id: 'testpubcid', atype: 1 }] }]); } finally { coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1889,7 +1889,7 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] + uids: [{ id: 'testpubcid', atype: 1 }] }]) } finally { localStorage.removeItem('pubcid'); @@ -1908,7 +1908,7 @@ describe('User ID', function () { const eids = await getGlobalEids(); expect(eids).to.eql([{ source: 'pubcid.org', - uids: [{id: 'testpubcid', atype: 1}] + uids: [{ id: 'testpubcid', atype: 1 }] }]); } finally { coreStorage.setCookie('pubcid', '', EXPIRED_COOKIE_DATE); @@ -1918,7 +1918,7 @@ describe('User ID', function () { it('test hook from pubcommonid config value object', async function () { init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); - config.setConfig(getConfigValueMock('pubCommonId', {'pubcidvalue': 'testpubcidvalue'})); + config.setConfig(getConfigValueMock('pubCommonId', { 'pubcidvalue': 'testpubcidvalue' })); expect(await getGlobalEids()).to.not.exist; // "pubcidvalue" is an un-known submodule for USER_IDS_CONFIG in eids.js }); @@ -1997,9 +1997,9 @@ describe('User ID', function () { userSync: { syncDelay: 0, userIds: [{ - name: 'pubCommonId', storage: {name: 'pubcid', type: 'cookie'} + name: 'pubCommonId', storage: { name: 'pubcid', type: 'cookie' } }, { - name: 'mockId', storage: {name: 'MOCKID', type: 'cookie'} + name: 'mockId', storage: { name: 'MOCKID', type: 'cookie' } }] } }); @@ -2014,7 +2014,7 @@ describe('User ID', function () { }, getId: function (config, consentData, storedId) { if (storedId) return {}; - return {id: {'MOCKID': '1234'}}; + return { id: { 'MOCKID': '1234' } }; }, eids: { mid: { @@ -2037,7 +2037,7 @@ describe('User ID', function () { discloseStorageUse.before(discloseStorageHook) }) after(() => { - discloseStorageUse.getHooks({hook: discloseStorageHook}).remove(); + discloseStorageUse.getHooks({ hook: discloseStorageHook }).remove(); }) beforeEach(() => { disclose = sinon.stub(); @@ -2133,7 +2133,7 @@ describe('User ID', function () { }; }, getId: function () { - return {id: `${name}Value`}; + return { id: `${name}Value` }; }, eids: { [name]: { @@ -2158,12 +2158,12 @@ describe('User ID', function () { userSync: { syncDelay: 0, userIds: MOCK_IDS.map(name => ({ - name, storage: {name, type: 'cookie'} + name, storage: { name, type: 'cookie' } })) } }); const eids = await getGlobalEids(); - const activeSources = eids.map(({source}) => source); + const activeSources = eids.map(({ source }) => source); expect(Array.from(new Set(activeSources))).to.have.members([MOCK_IDS[1]]); }); }) @@ -2197,7 +2197,7 @@ describe('User ID', function () { it('pubcid callback with url', function () { let customCfg = getConfigMock(['pubCommonId', 'pubcid', 'cookie']); - customCfg = addConfig(customCfg, 'params', {pixelUrl: '/any/pubcid/url'}); + customCfg = addConfig(customCfg, 'params', { pixelUrl: '/any/pubcid/url' }); init(config); setSubmoduleRegistry([sharedIdSystemSubmodule]); @@ -2303,7 +2303,7 @@ describe('User ID', function () { }); function setStorage({ - val = JSON.stringify({id: '1234'}), + val = JSON.stringify({ id: '1234' }), lastDelta = 60 * 1000, cst = null } = {}) { @@ -2315,13 +2315,13 @@ describe('User ID', function () { } it('calls getId if no stored consent data and refresh is not needed', function () { - setStorage({lastDelta: 1000}); + setStorage({ lastDelta: 1000 }); config.setConfig(userIdConfig); let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.calledOnce(mockGetId); sinon.assert.calledOnce(mockDecode); sinon.assert.notCalled(mockExtendId); @@ -2335,7 +2335,7 @@ describe('User ID', function () { let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.calledOnce(mockGetId); sinon.assert.calledOnce(mockDecode); sinon.assert.notCalled(mockExtendId); @@ -2343,13 +2343,13 @@ describe('User ID', function () { }); it('calls getId if empty stored consent and refresh not needed', function () { - setStorage({cst: ''}); + setStorage({ cst: '' }); config.setConfig(userIdConfig); let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.calledOnce(mockGetId); sinon.assert.calledOnce(mockDecode); sinon.assert.notCalled(mockExtendId); @@ -2357,7 +2357,7 @@ describe('User ID', function () { }); it('calls getId if stored consent does not match current consent and refresh not needed', function () { - setStorage({cst: getConsentHash()}); + setStorage({ cst: getConsentHash() }); gdprDataHandler.setConsentData({ consentString: 'different' }); @@ -2367,7 +2367,7 @@ describe('User ID', function () { let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.calledOnce(mockGetId); sinon.assert.calledOnce(mockDecode); sinon.assert.notCalled(mockExtendId); @@ -2375,14 +2375,14 @@ describe('User ID', function () { }); it('does not call getId if stored consent matches current consent and refresh not needed', function () { - setStorage({lastDelta: 1000, cst: getConsentHash()}); + setStorage({ lastDelta: 1000, cst: getConsentHash() }); config.setConfig(userIdConfig); let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.notCalled(mockGetId); sinon.assert.calledOnce(mockDecode); sinon.assert.calledOnce(mockExtendId); @@ -2390,16 +2390,16 @@ describe('User ID', function () { }); it('calls getId with the list of enabled storage types', function() { - setStorage({lastDelta: 1000}); + setStorage({ lastDelta: 1000 }); config.setConfig(userIdConfig); let innerAdUnits; return runBidsHook((config) => { innerAdUnits = config.adUnits - }, {adUnits}).then(() => { + }, { adUnits }).then(() => { sinon.assert.calledOnce(mockGetId); - expect(mockGetId.getCall(0).args[0].enabledStorageTypes).to.deep.equal([ userIdConfig.userSync.userIds[0].storage.type ]); + expect(mockGetId.getCall(0).args[0].enabledStorageTypes).to.deep.equal([userIdConfig.userSync.userIds[0].storage.type]); }); }); }); @@ -2409,10 +2409,10 @@ describe('User ID', function () { return { name, getId() { - return {id: value} + return { id: value } }, decode(d) { - return {[name]: d} + return { [name]: d } }, onDataDeletionRequest: sinon.stub() } @@ -2428,7 +2428,7 @@ describe('User ID', function () { cfg1 = getStorageMock('id1', 'id1', 'cookie'); cfg2 = getStorageMock('id2', 'id2', 'html5'); cfg3 = getStorageMock('id3', 'id3', 'cookie&html5'); - cfg4 = {name: 'id4', value: {id4: 'val4'}}; + cfg4 = { name: 'id4', value: { id4: 'val4' } }; setSubmoduleRegistry([mod1, mod2, mod3, mod4]); config.setConfig({ auctionDelay: 1, @@ -2453,10 +2453,10 @@ describe('User ID', function () { it('invokes onDataDeletionRequest', () => { requestDataDeletion(sinon.stub()); - sinon.assert.calledWith(mod1.onDataDeletionRequest, cfg1, {id1: 'val1'}); - sinon.assert.calledWith(mod2.onDataDeletionRequest, cfg2, {id2: 'val2'}); - sinon.assert.calledWith(mod3.onDataDeletionRequest, cfg3, {id3: 'val3'}); - sinon.assert.calledWith(mod4.onDataDeletionRequest, cfg4, {id4: 'val4'}); + sinon.assert.calledWith(mod1.onDataDeletionRequest, cfg1, { id1: 'val1' }); + sinon.assert.calledWith(mod2.onDataDeletionRequest, cfg2, { id2: 'val2' }); + sinon.assert.calledWith(mod3.onDataDeletionRequest, cfg3, { id3: 'val3' }); + sinon.assert.calledWith(mod4.onDataDeletionRequest, cfg4, { id4: 'val4' }); }); describe('does not choke when onDataDeletionRequest', () => { @@ -2467,7 +2467,7 @@ describe('User ID', function () { it(t, () => { setup(); const next = sinon.stub(); - const arg = {random: 'value'}; + const arg = { random: 'value' }; requestDataDeletion(next, arg); sinon.assert.calledOnce(mod2.onDataDeletionRequest); sinon.assert.calledOnce(mod3.onDataDeletionRequest); @@ -2505,7 +2505,7 @@ describe('User ID', function () { userSync: { encryptedSignalSources: { registerDelay: 0, - sources: [{source: ['pubcid.org'], encrypt: false}] + sources: [{ source: ['pubcid.org'], encrypt: false }] } } }); @@ -2578,10 +2578,10 @@ describe('User ID', function () { } } setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {uid2: {id: 'uid2_value'}}}, null, EIDS), - createMockIdSubmodule('mockId2Module', {id: {pubcid: 'pubcid_value', lipb: {lipbid: 'lipbid_value_from_mockId2Module'}}}, null, EIDS), - createMockIdSubmodule('mockId3Module', {id: {uid2: {id: 'uid2_value_from_mockId3Module'}, pubcid: 'pubcid_value_from_mockId3Module', lipb: {lipbid: 'lipbid_value'}, merkleId: {id: 'merkleId_value_from_mockId3Module'}}}, null, EIDS), - createMockIdSubmodule('mockId4Module', {id: {merkleId: {id: 'merkleId_value'}}}, null, EIDS) + createMockIdSubmodule('mockId1Module', { id: { uid2: { id: 'uid2_value' } } }, null, EIDS), + createMockIdSubmodule('mockId2Module', { id: { pubcid: 'pubcid_value', lipb: { lipbid: 'lipbid_value_from_mockId2Module' } } }, null, EIDS), + createMockIdSubmodule('mockId3Module', { id: { uid2: { id: 'uid2_value_from_mockId3Module' }, pubcid: 'pubcid_value_from_mockId3Module', lipb: { lipbid: 'lipbid_value' }, merkleId: { id: 'merkleId_value_from_mockId3Module' } } }, null, EIDS), + createMockIdSubmodule('mockId4Module', { id: { merkleId: { id: 'merkleId_value' } } }, null, EIDS) ]); config.setConfig({ userSync: { @@ -2627,7 +2627,7 @@ describe('User ID', function () { userSync: { auctionDelay: 10, userIds: [{ - name: 'pubCommonId', value: {'pubcid': '11111'} + name: 'pubCommonId', value: { 'pubcid': '11111' } }] } }); @@ -2670,7 +2670,7 @@ describe('User ID', function () { userSync: { auctionDelay: 10, userIds: [{ - name: 'pubCommonId', value: {'pubcid': '11111'} + name: 'pubCommonId', value: { 'pubcid': '11111' } }] } }); @@ -2689,10 +2689,10 @@ describe('User ID', function () { const merkleEids = createMockEid('merkleId', 'merkleinc.com') setSubmoduleRegistry([ - createMockIdSubmodule('mockId1Module', {id: {uid2: {id: 'uid2_value'}}}, null, uid2Eids), - createMockIdSubmodule('mockId2Module', {id: {pubcid: 'pubcid_value', lipb: {lipbid: 'lipbid_value_from_mockId2Module'}}}, null, {...pubcEids, ...liveIntentEids}), - createMockIdSubmodule('mockId3Module', {id: {uid2: {id: 'uid2_value_from_mockId3Module'}, pubcid: 'pubcid_value_from_mockId3Module', lipb: {lipbid: 'lipbid_value'}, merkleId: {id: 'merkleId_value_from_mockId3Module'}}}, null, {...uid2Eids, ...pubcEids, ...liveIntentEids}), - createMockIdSubmodule('mockId4Module', {id: {merkleId: {id: 'merkleId_value'}}}, null, merkleEids) + createMockIdSubmodule('mockId1Module', { id: { uid2: { id: 'uid2_value' } } }, null, uid2Eids), + createMockIdSubmodule('mockId2Module', { id: { pubcid: 'pubcid_value', lipb: { lipbid: 'lipbid_value_from_mockId2Module' } } }, null, { ...pubcEids, ...liveIntentEids }), + createMockIdSubmodule('mockId3Module', { id: { uid2: { id: 'uid2_value_from_mockId3Module' }, pubcid: 'pubcid_value_from_mockId3Module', lipb: { lipbid: 'lipbid_value' }, merkleId: { id: 'merkleId_value_from_mockId3Module' } } }, null, { ...uid2Eids, ...pubcEids, ...liveIntentEids }), + createMockIdSubmodule('mockId4Module', { id: { merkleId: { id: 'merkleId_value' } } }, null, merkleEids) ]); config.setConfig({ userSync: { @@ -2711,10 +2711,10 @@ describe('User ID', function () { }); const ids = { - 'uidapi.com': {'uid2': {id: 'uid2_value_from_mockId3Module'}}, - 'pubcid.org': {'pubcid': 'pubcid_value'}, - 'liveintent.com': {'lipb': {lipbid: 'lipbid_value_from_mockId2Module'}}, - 'merkleinc.com': {'merkleId': {id: 'merkleId_value'}} + 'uidapi.com': { 'uid2': { id: 'uid2_value_from_mockId3Module' } }, + 'pubcid.org': { 'pubcid': 'pubcid_value' }, + 'liveintent.com': { 'lipb': { lipbid: 'lipbid_value_from_mockId2Module' } }, + 'merkleinc.com': { 'merkleId': { id: 'merkleId_value' } } }; return getGlobal().getUserIdsAsync().then(() => { @@ -2751,7 +2751,7 @@ describe('User ID', function () { source: `${extraKey}.com`, atype: 1, getUidExt() { - return {provider: `${key}Module`} + return { provider: `${key}Module` } } }])) } @@ -2775,10 +2775,10 @@ describe('User ID', function () { ]); }) - function enrich({global = {}, bidder = {}} = {}) { + function enrich({ global = {}, bidder = {} } = {}) { return getGlobal().getUserIdsAsync().then(() => { - enrichEids({global, bidder}); - return {global, bidder}; + enrichEids({ global, bidder }); + return { global, bidder }; }) } @@ -2790,7 +2790,7 @@ describe('User ID', function () { atype: 1, }; if (!owner) { - uid.ext = {provider: module} + uid.ext = { provider: module } } return { source: `${key}.com`, @@ -2801,7 +2801,7 @@ describe('User ID', function () { function bidderEids(bidderMappings) { return Object.fromEntries( - Object.entries(bidderMappings).map(([bidder, mapping]) => [bidder, {user: {ext: {eids: eidsFrom(mapping)}}}]) + Object.entries(bidderMappings).map(([bidder, mapping]) => [bidder, { user: { ext: { eids: eidsFrom(mapping) } } }]) ) } @@ -2818,7 +2818,7 @@ describe('User ID', function () { ] } }); - return enrich().then(({global}) => { + return enrich().then(({ global }) => { expect(global.user.ext.eids).to.eql(eidsFrom({ mockId1: 'mockId1Module' })) @@ -2834,7 +2834,7 @@ describe('User ID', function () { ] } }); - return enrich().then(({global}) => { + return enrich().then(({ global }) => { expect(global.user?.ext?.eids).to.not.exist; }); }); @@ -2854,7 +2854,7 @@ describe('User ID', function () { ] } }); - return enrich().then(({global}) => { + return enrich().then(({ global }) => { expect(global.user.ext.eids).to.eql(eidsFrom({ mockId1: 'mockId3Module', mockId2: 'mockId2Module', @@ -2873,7 +2873,7 @@ describe('User ID', function () { ] } }); - return enrich().then(({global, bidder}) => { + return enrich().then(({ global, bidder }) => { expect(global.user.ext.eids).to.eql(eidsFrom({ mockId4: 'mockId4Module' })); @@ -2928,7 +2928,7 @@ describe('User ID', function () { it('should restrict ID if it comes from restricted modules', async () => { setup(); - const {global, bidder} = await enrich(); + const { global, bidder } = await enrich(); expect(global).to.eql({}); expect(bidder).to.eql(bidderEids({ bidderA: { @@ -2945,7 +2945,7 @@ describe('User ID', function () { it('should use secondary module restrictions if ID comes from it', async () => { idValues.mockId1 = []; setup(); - const {global, bidder} = await enrich(); + const { global, bidder } = await enrich(); expect(global).to.eql({}); expect(bidder).to.eql(bidderEids({ bidderA: { @@ -2964,7 +2964,7 @@ describe('User ID', function () { idValues.mockId2 = []; idValues.mockId3 = []; setup(); - const {global, bidder} = await enrich(); + const { global, bidder } = await enrich(); expect(global.user.ext.eids).to.eql(eidsFrom({ mockId1: 'mockId4Module' })); @@ -2989,7 +2989,7 @@ describe('User ID', function () { } it('should not restrict if primary id is available', async () => { setup(); - const {global, bidder} = await enrich(); + const { global, bidder } = await enrich(); expect(global.user.ext.eids).to.eql(eidsFrom({ mockId1: 'mockId1Module' })); @@ -2998,7 +2998,7 @@ describe('User ID', function () { it('should use secondary modules\' restrictions if they provide the ID', async () => { idValues.mockId1 = []; setup(); - const {global, bidder} = await enrich(); + const { global, bidder } = await enrich(); expect(global).to.eql({}); expect(bidder).to.eql(bidderEids({ bidderA: { @@ -3027,7 +3027,7 @@ describe('User ID', function () { ] } }); - return enrich().then(({global, bidder}) => { + return enrich().then(({ global, bidder }) => { expect(global.user?.ext?.eids).to.not.exist; expect(bidder).to.eql(bidderEids({ bidderA: { @@ -3053,17 +3053,17 @@ describe('User ID', function () { ] } }); - const globalEids = [{pub: 'provided'}]; - const bidderAEids = [{bidder: 'A'}] + const globalEids = [{ pub: 'provided' }]; + const bidderAEids = [{ bidder: 'A' }] const fpd = { - global: {user: {ext: {eids: globalEids}}}, + global: { user: { ext: { eids: globalEids } } }, bidder: { bidderA: { - user: {ext: {eids: bidderAEids}} + user: { ext: { eids: bidderAEids } } } } } - return enrich(fpd).then(({global, bidder}) => { + return enrich(fpd).then(({ global, bidder }) => { expect(global.user.ext.eids).to.eql(globalEids.concat(eidsFrom({ mockId4: 'mockId4Module' }))); @@ -3094,7 +3094,7 @@ describe('User ID', function () { mockIdSubmodule(UNALLOWED_MODULE), ]); - const unregisterRule = registerActivityControl(ACTIVITY_ENRICH_EIDS, 'ruleName', ({componentName, init}) => { + const unregisterRule = registerActivityControl(ACTIVITY_ENRICH_EIDS, 'ruleName', ({ componentName, init }) => { if (componentName === 'mockId3Module' && init === false) { return ({ allow: false, reason: "disabled" }); } }); @@ -3236,8 +3236,8 @@ describe('User ID', function () { it('should properly map registry to submodule containers for non-empty previous submodule containers', () => { const previousSubmoduleContainers = [ - {submodule: {name: 'notSharedId'}, config: {name: 'notSharedId'}}, - {submodule: {name: 'notSharedId2'}, config: {name: 'notSharedId2'}}, + { submodule: { name: 'notSharedId' }, config: { name: 'notSharedId' } }, + { submodule: { name: 'notSharedId2' }, config: { name: 'notSharedId2' } }, ]; const submoduleRegistry = [ sharedIdSystemSubmodule, @@ -3252,14 +3252,14 @@ describe('User ID', function () { it('should properly map registry to submodule containers for retainConfig flag', () => { const previousSubmoduleContainers = [ - {submodule: {name: 'shouldBeKept'}, config: {name: 'shouldBeKept'}}, + { submodule: { name: 'shouldBeKept' }, config: { name: 'shouldBeKept' } }, ]; const submoduleRegistry = [ sharedIdSystemSubmodule, createMockIdSubmodule('shouldBeKept', { id: { uid2: { id: 'uid2_value' } } }, null, null), ]; const configRegistry = [{ name: 'sharedId' }]; - const result = generateSubmoduleContainers({retainConfig: true}, configRegistry, previousSubmoduleContainers, submoduleRegistry); + const result = generateSubmoduleContainers({ retainConfig: true }, configRegistry, previousSubmoduleContainers, submoduleRegistry); expect(result).to.have.lengthOf(2); expect(result[0].submodule.name).to.eql('sharedId'); expect(result[1].submodule.name).to.eql('shouldBeKept'); @@ -3267,8 +3267,8 @@ describe('User ID', function () { it('should properly map registry to submodule containers for autoRefresh flag', () => { const previousSubmoduleContainers = [ - {submodule: {name: 'modified'}, config: {name: 'modified', auctionDelay: 300}}, - {submodule: {name: 'unchanged'}, config: {name: 'unchanged', auctionDelay: 300}}, + { submodule: { name: 'modified' }, config: { name: 'modified', auctionDelay: 300 } }, + { submodule: { name: 'unchanged' }, config: { name: 'unchanged', auctionDelay: 300 } }, ]; const submoduleRegistry = [ createMockIdSubmodule('modified', { id: { uid2: { id: 'uid2_value' } } }, null, null), @@ -3276,11 +3276,11 @@ describe('User ID', function () { createMockIdSubmodule('unchanged', { id: { uid2: { id: 'uid2_value' } } }, null, null), ]; const configRegistry = [ - {name: 'modified', auctionDelay: 200}, - {name: 'new'}, - {name: 'unchanged', auctionDelay: 300}, + { name: 'modified', auctionDelay: 200 }, + { name: 'new' }, + { name: 'unchanged', auctionDelay: 300 }, ]; - const result = generateSubmoduleContainers({autoRefresh: true}, configRegistry, previousSubmoduleContainers, submoduleRegistry); + const result = generateSubmoduleContainers({ autoRefresh: true }, configRegistry, previousSubmoduleContainers, submoduleRegistry); expect(result).to.have.lengthOf(3); const itemsWithRefreshIds = result.filter(item => item.refreshIds); const submoduleNames = itemsWithRefreshIds.map(item => item.submodule.name); @@ -3305,7 +3305,7 @@ describe('User ID', function () { before(() => { setSubmoduleRegistry([ - createMockIdSubmodule(UID_MODULE_NAME, {id: {uid2: {id: 'uid2_value'}}}, null, []), + createMockIdSubmodule(UID_MODULE_NAME, { id: { uid2: { id: 'uid2_value' } } }, null, []), ]); }) @@ -3319,15 +3319,15 @@ describe('User ID', function () { }); it('should not warn when reading', () => { - config.setConfig({userSync}); - const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME}); + config.setConfig({ userSync }); + const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME }); storage.cookiesAreEnabled(); sinon.assert.notCalled(warnLogSpy); }) it('should warn and allow userId module to store data for enforceStorageType unset', () => { - config.setConfig({userSync}); - const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME}); + config.setConfig({ userSync }); + const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME }); storage.setCookie(cookieName, 'value', 20000); sinon.assert.calledWith(warnLogSpy, `${UID_MODULE_NAME} attempts to store data in ${STORAGE_TYPE_COOKIES} while configuration allows ${STORAGE_TYPE_LOCALSTORAGE}.`); expect(storage.getCookie(cookieName)).to.eql('value'); @@ -3340,7 +3340,7 @@ describe('User ID', function () { ...userSync, } }) - const storage = getStorageManager({moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME}); + const storage = getStorageManager({ moduleType: MODULE_TYPE_UID, moduleName: UID_MODULE_NAME }); storage.setCookie(cookieName, 'value', 20000); expect(storage.getCookie(cookieName)).to.not.exist; }); diff --git a/test/spec/modules/utiqIdSystem_spec.js b/test/spec/modules/utiqIdSystem_spec.js index 67a40928116..64cceebedbd 100644 --- a/test/spec/modules/utiqIdSystem_spec.js +++ b/test/spec/modules/utiqIdSystem_spec.js @@ -7,7 +7,7 @@ describe('utiqIdSystem', () => { const getStorageData = (idGraph) => { if (!idGraph) { - idGraph = {id: 501, domain: ''}; + idGraph = { id: 501, domain: '' }; } return { 'connectId': { @@ -105,7 +105,7 @@ describe('utiqIdSystem', () => { 'atid': 'atidValue', }; - const response = utiqIdSubmodule.getId({params: {maxDelayTime: 200}}); + const response = utiqIdSubmodule.getId({ params: { maxDelayTime: 200 } }); expect(response).to.have.property('callback'); expect(response.callback.toString()).contain('result(callback)'); @@ -139,12 +139,12 @@ describe('utiqIdSystem', () => { VALID_API_RESPONSES.forEach(responseData => { it('should return a newly constructed object with the utiq for a payload with {utiq: value}', () => { expect(utiqIdSubmodule.decode(responseData.payload)).to.deep.equal( - {utiq: responseData.expected} + { utiq: responseData.expected } ); }); }); - [{}, '', {foo: 'bar'}].forEach((response) => { + [{}, '', { foo: 'bar' }].forEach((response) => { it(`should return null for an invalid response "${JSON.stringify(response)}"`, () => { expect(utiqIdSubmodule.decode(response)).to.be.null; }); diff --git a/test/spec/modules/utiqMtpIdSystem_spec.js b/test/spec/modules/utiqMtpIdSystem_spec.js index 19c42ba1495..7d91750683d 100644 --- a/test/spec/modules/utiqMtpIdSystem_spec.js +++ b/test/spec/modules/utiqMtpIdSystem_spec.js @@ -6,7 +6,7 @@ describe('utiqMtpIdSystem', () => { const getStorageData = (idGraph) => { if (!idGraph) { - idGraph = {id: 501, domain: ''}; + idGraph = { id: 501, domain: '' }; } return { 'connectId': { @@ -104,7 +104,7 @@ describe('utiqMtpIdSystem', () => { 'mtid': 'mtidValue', }; - const response = utiqMtpIdSubmodule.getId({params: {maxDelayTime: 200}}); + const response = utiqMtpIdSubmodule.getId({ params: { maxDelayTime: 200 } }); expect(response).to.have.property('callback'); expect(response.callback.toString()).contain('result(callback)'); @@ -138,12 +138,12 @@ describe('utiqMtpIdSystem', () => { VALID_API_RESPONSES.forEach(responseData => { it('should return a newly constructed object with the utiqMtp for a payload with {utiqMtp: value}', () => { expect(utiqMtpIdSubmodule.decode(responseData.payload)).to.deep.equal( - {utiqMtp: responseData.expected} + { utiqMtp: responseData.expected } ); }); }); - [{}, '', {foo: 'bar'}].forEach((response) => { + [{}, '', { foo: 'bar' }].forEach((response) => { it(`should return null for an invalid response "${JSON.stringify(response)}"`, () => { expect(utiqMtpIdSubmodule.decode(response)).to.be.null; }); diff --git a/test/spec/modules/validationFpdModule_spec.js b/test/spec/modules/validationFpdModule_spec.js index 73e3cbbfcab..12935ec5350 100644 --- a/test/spec/modules/validationFpdModule_spec.js +++ b/test/spec/modules/validationFpdModule_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import * as utils from 'src/utils.js'; import { filterArrayData, @@ -65,7 +65,7 @@ describe('the first party data validation module', function () { it('returns empty array if no valid data', function () { const arr = [{}]; const path = 'site.children.cat'; - const child = {type: 'string'}; + const child = { type: 'string' }; const parent = 'site'; const key = 'cat'; const validated = filterArrayData(arr, child, path, parent, key); @@ -73,9 +73,9 @@ describe('the first party data validation module', function () { }); it('filters invalid type of array data', function () { - const arr = ['foo', {test: 1}]; + const arr = ['foo', { test: 1 }]; const path = 'site.children.cat'; - const child = {type: 'string'}; + const child = { type: 'string' }; const parent = 'site'; const key = 'cat'; const validated = filterArrayData(arr, child, path, parent, key); @@ -83,9 +83,9 @@ describe('the first party data validation module', function () { }); it('filters all data for missing required children', function () { - const arr = [{test: 1}]; + const arr = [{ test: 1 }]; const path = 'site.children.content.children.data'; - const child = {type: 'object'}; + const child = { type: 'object' }; const parent = 'site'; const key = 'data'; const validated = filterArrayData(arr, child, path, parent, key); @@ -93,9 +93,9 @@ describe('the first party data validation module', function () { }); it('filters all data for invalid required children types', function () { - const arr = [{name: 'foo', segment: 1}]; + const arr = [{ name: 'foo', segment: 1 }]; const path = 'site.children.content.children.data'; - const child = {type: 'object'}; + const child = { type: 'object' }; const parent = 'site'; const key = 'data'; const validated = filterArrayData(arr, child, path, parent, key); @@ -103,13 +103,13 @@ describe('the first party data validation module', function () { }); it('returns only data with valid required nested children types', function () { - const arr = [{name: 'foo', segment: [{id: '1'}, {id: 2}, 'foobar']}]; + const arr = [{ name: 'foo', segment: [{ id: '1' }, { id: 2 }, 'foobar'] }]; const path = 'site.children.content.children.data'; - const child = {type: 'object'}; + const child = { type: 'object' }; const parent = 'site'; const key = 'data'; const validated = filterArrayData(arr, child, path, parent, key); - expect(validated).to.deep.equal([{name: 'foo', segment: [{id: '1'}]}]); + expect(validated).to.deep.equal([{ name: 'foo', segment: [{ id: '1' }] }]); }); }); @@ -189,8 +189,8 @@ describe('the first party data validation module', function () { } }; - duplicate.user.data[0].segment.push({test: 3}); - duplicate.user.data[0].segment[0] = {foo: 'bar'}; + duplicate.user.data[0].segment.push({ test: 3 }); + duplicate.user.data[0].segment[0] = { foo: 'bar' }; validated = validateFpd(duplicate); expect(validated).to.deep.equal(expected); @@ -227,7 +227,7 @@ describe('the first party data validation module', function () { } }; - duplicate.site.content.data[0].segment.push({test: 3}); + duplicate.site.content.data[0].segment.push({ test: 3 }); validated = validateFpd(duplicate); expect(validated).to.deep.equal(expected); @@ -265,7 +265,7 @@ describe('the first party data validation module', function () { } }; - duplicate.site.content.data[0].segment.push({test: 3}); + duplicate.site.content.data[0].segment.push({ test: 3 }); validated = validateFpd(duplicate); expect(validated).to.deep.equal(expected); @@ -304,7 +304,7 @@ describe('the first party data validation module', function () { } }; - duplicate.site.content.data[0].segment.push({test: 3}); + duplicate.site.content.data[0].segment.push({ test: 3 }); validated = validateFpd(duplicate); expect(validated).to.deep.equal(expected); diff --git a/test/spec/modules/vdoaiBidAdapter_spec.js b/test/spec/modules/vdoaiBidAdapter_spec.js index 4f3d9621e13..5514844f8ce 100644 --- a/test/spec/modules/vdoaiBidAdapter_spec.js +++ b/test/spec/modules/vdoaiBidAdapter_spec.js @@ -349,7 +349,7 @@ describe('vdoaiBidAdapter', function () { }) describe('interpretBannerResponse', function () { const resObject = { - body: [ { + body: [{ requestId: '123', cpm: 0.3, width: 320, @@ -363,7 +363,7 @@ describe('vdoaiBidAdapter', function () { advertiserDomains: ['example.com'], mediaType: 'banner' } - } ] + }] }; let serverResponses = spec.interpretResponse(resObject); it('Returns an array of valid server responses if response object is valid', function () { @@ -392,7 +392,7 @@ describe('vdoaiBidAdapter', function () { }); describe('interpretVideoResponse', function () { const resObject = { - body: [ { + body: [{ requestId: '123', cpm: 0.3, width: 320, @@ -406,7 +406,7 @@ describe('vdoaiBidAdapter', function () { advertiserDomains: ['example.com'], mediaType: 'video' } - } ] + }] }; let serverResponses = spec.interpretResponse(resObject); it('Returns an array of valid server responses if response object is valid', function () { @@ -494,7 +494,7 @@ describe('vdoaiBidAdapter', function () { }; it('should skip responses which do not contain required params', function() { const bidResponses = { - body: [ { + body: [{ cpm: 0.3, ttl: 1000, currency: 'USD', @@ -502,25 +502,25 @@ describe('vdoaiBidAdapter', function () { advertiserDomains: ['example.com'], mediaType: 'banner' } - }, resObject ] + }, resObject] } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); + expect(spec.interpretResponse(bidResponses)).to.deep.equal([resObject]); }); it('should skip responses which do not contain advertiser domains', function() { const resObjectWithoutAdvertiserDomains = Object.assign({}, resObject); resObjectWithoutAdvertiserDomains.meta = Object.assign({}, resObject.meta); delete resObjectWithoutAdvertiserDomains.meta.advertiserDomains; const bidResponses = { - body: [ resObjectWithoutAdvertiserDomains, resObject ] + body: [resObjectWithoutAdvertiserDomains, resObject] } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); + expect(spec.interpretResponse(bidResponses)).to.deep.equal([resObject]); }); it('should return responses which contain empty advertiser domains', function() { const resObjectWithEmptyAdvertiserDomains = Object.assign({}, resObject); resObjectWithEmptyAdvertiserDomains.meta = Object.assign({}, resObject.meta); resObjectWithEmptyAdvertiserDomains.meta.advertiserDomains = []; const bidResponses = { - body: [ resObjectWithEmptyAdvertiserDomains, resObject ] + body: [resObjectWithEmptyAdvertiserDomains, resObject] } expect(spec.interpretResponse(bidResponses)).to.deep.equal([resObjectWithEmptyAdvertiserDomains, resObject]); }); @@ -529,9 +529,9 @@ describe('vdoaiBidAdapter', function () { resObjectWithoutMetaMediaType.meta = Object.assign({}, resObject.meta); delete resObjectWithoutMetaMediaType.meta.mediaType; const bidResponses = { - body: [ resObjectWithoutMetaMediaType, resObject ] + body: [resObjectWithoutMetaMediaType, resObject] } - expect(spec.interpretResponse(bidResponses)).to.deep.equal([ resObject ]); + expect(spec.interpretResponse(bidResponses)).to.deep.equal([resObject]); }); }); describe('getUserSyncs', function () { diff --git a/test/spec/modules/verbenBidAdapter_spec.js b/test/spec/modules/verbenBidAdapter_spec.js new file mode 100644 index 00000000000..9864e9d2b70 --- /dev/null +++ b/test/spec/modules/verbenBidAdapter_spec.js @@ -0,0 +1,478 @@ +import { expect } from 'chai'; +import { spec } from '../../../modules/verbenBidAdapter.js'; +import { BANNER, VIDEO, NATIVE } from '../../../src/mediaTypes.js'; +import { getUniqueIdentifierStr } from '../../../src/utils.js'; + +const bidder = 'verben'; + +describe('VerbenBidAdapter', function () { + const userIdAsEids = [{ + source: 'test.org', + uids: [{ + id: '01**********', + atype: 1, + ext: { + third: '01***********' + } + }] + }]; + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + placementId: 'testBanner' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [VIDEO]: { + playerSize: [[300, 300]], + minduration: 5, + maxduration: 60 + } + }, + params: { + placementId: 'testVideo' + }, + userIdAsEids + }, + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [NATIVE]: { + native: { + title: { + required: true + }, + body: { + required: true + }, + icon: { + required: true, + size: [64, 64] + } + } + } + }, + params: { + placementId: 'testNative' + }, + userIdAsEids + } + ]; + + const invalidBid = { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + + } + } + + const bidderRequest = { + uspConsent: '1---', + gdprConsent: { + consentString: 'COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA.IFoEUQQgAIQwgIwQABAEAAAAOIAACAIAAAAQAIAgEAACEAAAAAgAQBAAAAAAAGBAAgAAAAAAAFAAECAAAgAAQARAEQAAAAAJAAIAAgAAAYQEAAAQmAgBC3ZAYzUw', + vendorData: {} + }, + refererInfo: { + referer: 'https://test.com', + page: 'https://test.com' + }, + ortb2: { + device: { + w: 1512, + h: 982, + language: 'en-UK' + } + }, + timeout: 500 + }; + + describe('isBidRequestValid', function () { + it('Should return true if there are bidId, params and key parameters present', function () { + expect(spec.isBidRequestValid(bids[0])).to.be.true; + }); + it('Should return false if at least one of parameters is not present', function () { + expect(spec.isBidRequestValid(invalidBid)).to.be.false; + }); + }); + + describe('buildRequests', function () { + let serverRequest = spec.buildRequests(bids, bidderRequest); + + it('Creates a ServerRequest object with method, URL and data', function () { + expect(serverRequest).to.exist; + expect(serverRequest.method).to.exist; + expect(serverRequest.url).to.exist; + expect(serverRequest.data).to.exist; + }); + + it('Returns POST method', function () { + expect(serverRequest.method).to.equal('POST'); + }); + + it('Returns valid URL', function () { + expect(serverRequest.url).to.equal('https://east-node.verben.com/pbjs'); + }); + + it('Returns general data valid', function () { + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.all.keys('deviceWidth', + 'deviceHeight', + 'device', + 'language', + 'secure', + 'host', + 'page', + 'placements', + 'coppa', + 'ccpa', + 'gdpr', + 'tmax', + 'bcat', + 'badv', + 'bapp', + 'battr' + ); + expect(data.deviceWidth).to.be.a('number'); + expect(data.deviceHeight).to.be.a('number'); + expect(data.language).to.be.a('string'); + expect(data.secure).to.be.within(0, 1); + expect(data.host).to.be.a('string'); + expect(data.page).to.be.a('string'); + expect(data.coppa).to.be.a('number'); + expect(data.gdpr).to.be.a('object'); + expect(data.ccpa).to.be.a('string'); + expect(data.tmax).to.be.a('number'); + expect(data.placements).to.have.lengthOf(3); + }); + + it('Returns valid placements', function () { + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.placementId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('publisher'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns valid endpoints', function () { + const bids = [ + { + bidId: getUniqueIdentifierStr(), + bidder: bidder, + mediaTypes: { + [BANNER]: { + sizes: [[300, 250]] + } + }, + params: { + endpointId: 'testBanner', + }, + userIdAsEids + } + ]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + + const { placements } = serverRequest.data; + for (let i = 0, len = placements.length; i < len; i++) { + const placement = placements[i]; + expect(placement.endpointId).to.be.oneOf(['testBanner', 'testVideo', 'testNative']); + expect(placement.adFormat).to.be.oneOf([BANNER, VIDEO, NATIVE]); + expect(placement.bidId).to.be.a('string'); + expect(placement.schain).to.be.an('object'); + expect(placement.bidfloor).to.exist.and.to.equal(0); + expect(placement.type).to.exist.and.to.equal('network'); + expect(placement.eids).to.exist.and.to.be.deep.equal(userIdAsEids); + + if (placement.adFormat === BANNER) { + expect(placement.sizes).to.be.an('array'); + } + switch (placement.adFormat) { + case BANNER: + expect(placement.sizes).to.be.an('array'); + break; + case VIDEO: + expect(placement.playerSize).to.be.an('array'); + expect(placement.minduration).to.be.an('number'); + expect(placement.maxduration).to.be.an('number'); + break; + case NATIVE: + expect(placement.native).to.be.an('object'); + break; + } + } + }); + + it('Returns data with gdprConsent and without uspConsent', function () { + delete bidderRequest.uspConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.gdpr).to.exist; + expect(data.gdpr).to.be.a('object'); + expect(data.gdpr).to.have.property('consentString'); + expect(data.gdpr).to.not.have.property('vendorData'); + expect(data.gdpr.consentString).to.equal(bidderRequest.gdprConsent.consentString); + expect(data.ccpa).to.not.exist; + delete bidderRequest.gdprConsent; + }); + + it('Returns data with uspConsent and without gdprConsent', function () { + bidderRequest.uspConsent = '1---'; + delete bidderRequest.gdprConsent; + serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data.ccpa).to.exist; + expect(data.ccpa).to.be.a('string'); + expect(data.ccpa).to.equal(bidderRequest.uspConsent); + expect(data.gdpr).to.not.exist; + }); + }); + + describe('gpp consent', function () { + it('bidderRequest.gppConsent', () => { + bidderRequest.gppConsent = { + gppString: 'abc123', + applicableSections: [8] + }; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + + delete bidderRequest.gppConsent; + }) + + it('bidderRequest.ortb2.regs.gpp', () => { + bidderRequest.ortb2 = bidderRequest.ortb2 || {}; + bidderRequest.ortb2.regs = bidderRequest.ortb2.regs || {}; + bidderRequest.ortb2.regs.gpp = 'abc123'; + bidderRequest.ortb2.regs.gpp_sid = [8]; + + const serverRequest = spec.buildRequests(bids, bidderRequest); + const data = serverRequest.data; + expect(data).to.be.an('object'); + expect(data).to.have.property('gpp'); + expect(data).to.have.property('gpp_sid'); + }) + }); + + describe('interpretResponse', function () { + it('Should interpret banner response', function () { + const banner = { + body: [{ + mediaType: 'banner', + width: 300, + height: 250, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const bannerResponses = spec.interpretResponse(banner); + expect(bannerResponses).to.be.an('array').that.is.not.empty; + const dataItem = bannerResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'width', 'height', 'ad', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal(banner.body[0].requestId); + expect(dataItem.cpm).to.equal(banner.body[0].cpm); + expect(dataItem.width).to.equal(banner.body[0].width); + expect(dataItem.height).to.equal(banner.body[0].height); + expect(dataItem.ad).to.equal(banner.body[0].ad); + expect(dataItem.ttl).to.equal(banner.body[0].ttl); + expect(dataItem.creativeId).to.equal(banner.body[0].creativeId); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal(banner.body[0].currency); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret video response', function () { + const video = { + body: [{ + vastUrl: 'test.com', + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const videoResponses = spec.interpretResponse(video); + expect(videoResponses).to.be.an('array').that.is.not.empty; + + const dataItem = videoResponses[0]; + expect(dataItem).to.have.all.keys('requestId', 'cpm', 'vastUrl', 'ttl', 'creativeId', + 'netRevenue', 'currency', 'dealId', 'mediaType', 'meta'); + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.5); + expect(dataItem.vastUrl).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should interpret native response', function () { + const native = { + body: [{ + mediaType: 'native', + native: { + clickUrl: 'test.com', + title: 'Test', + image: 'test.com', + impressionTrackers: ['test.com'], + }, + ttl: 120, + cpm: 0.4, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + meta: { + advertiserDomains: ['google.com'], + advertiserId: 1234 + } + }] + }; + const nativeResponses = spec.interpretResponse(native); + expect(nativeResponses).to.be.an('array').that.is.not.empty; + + const dataItem = nativeResponses[0]; + expect(dataItem).to.have.keys('requestId', 'cpm', 'ttl', 'creativeId', 'netRevenue', 'currency', 'mediaType', 'native', 'meta'); + expect(dataItem.native).to.have.keys('clickUrl', 'impressionTrackers', 'title', 'image') + expect(dataItem.requestId).to.equal('23fhj33i987f'); + expect(dataItem.cpm).to.equal(0.4); + expect(dataItem.native.clickUrl).to.equal('test.com'); + expect(dataItem.native.title).to.equal('Test'); + expect(dataItem.native.image).to.equal('test.com'); + expect(dataItem.native.impressionTrackers).to.be.an('array').that.is.not.empty; + expect(dataItem.native.impressionTrackers[0]).to.equal('test.com'); + expect(dataItem.ttl).to.equal(120); + expect(dataItem.creativeId).to.equal('2'); + expect(dataItem.netRevenue).to.be.true; + expect(dataItem.currency).to.equal('USD'); + expect(dataItem.meta).to.be.an('object').that.has.any.key('advertiserDomains'); + }); + it('Should return an empty array if invalid banner response is passed', function () { + const invBanner = { + body: [{ + width: 300, + cpm: 0.4, + ad: 'Test', + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + + const serverResponses = spec.interpretResponse(invBanner); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid video response is passed', function () { + const invVideo = { + body: [{ + mediaType: 'video', + cpm: 0.5, + requestId: '23fhj33i987f', + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invVideo); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid native response is passed', function () { + const invNative = { + body: [{ + mediaType: 'native', + clickUrl: 'test.com', + title: 'Test', + impressionTrackers: ['test.com'], + ttl: 120, + requestId: '23fhj33i987f', + creativeId: '2', + netRevenue: true, + currency: 'USD', + }] + }; + const serverResponses = spec.interpretResponse(invNative); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + it('Should return an empty array if invalid response is passed', function () { + const invalid = { + body: [{ + ttl: 120, + creativeId: '2', + netRevenue: true, + currency: 'USD', + dealId: '1' + }] + }; + const serverResponses = spec.interpretResponse(invalid); + expect(serverResponses).to.be.an('array').that.is.empty; + }); + }); +}); diff --git a/test/spec/modules/viantBidAdapter_spec.js b/test/spec/modules/viantBidAdapter_spec.js index 46717e1518c..7683578f2ce 100644 --- a/test/spec/modules/viantBidAdapter_spec.js +++ b/test/spec/modules/viantBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {spec, converter} from 'modules/viantBidAdapter.js'; -import {assert, expect} from 'chai'; -import {deepClone} from '../../../src/utils.js'; -import {buildWindowTree} from '../../helpers/refererDetectionHelper.js'; -import {detectReferer} from '../../../src/refererDetection.js'; +import { spec, converter } from 'modules/viantBidAdapter.js'; +import { assert, expect } from 'chai'; +import { deepClone } from '../../../src/utils.js'; +import { buildWindowTree } from '../../helpers/refererDetectionHelper.js'; +import { detectReferer } from '../../../src/refererDetection.js'; describe('viantOrtbBidAdapter', function () { function testBuildRequests(bidRequests, bidderRequestBase) { @@ -353,7 +353,7 @@ describe('viantOrtbBidAdapter', function () { } it('assert video and its fields is present in imp ', function () { - const requests = spec.buildRequests([makeBid()], {referrerInfo: {}}); + const requests = spec.buildRequests([makeBid()], { referrerInfo: {} }); const clonedRequests = deepClone(requests) assert.equal(clonedRequests[0].data.imp[0].video.mimes[0], 'video/mp4') assert.equal(clonedRequests[0].data.imp[0].video.maxduration, 31) @@ -400,8 +400,8 @@ describe('viantOrtbBidAdapter', function () { it('empty bid response test', function () { const request = testBuildRequests(baseBannerBidRequests, baseBidderRequest)[0]; - const bidResponse = {nbr: 0}; // Unknown error - const bids = spec.interpretResponse({body: bidResponse}, request); + const bidResponse = { nbr: 0 }; // Unknown error + const bids = spec.interpretResponse({ body: bidResponse }, request); expect(bids.length).to.equal(0); }); @@ -421,7 +421,7 @@ describe('viantOrtbBidAdapter', function () { }], cur: 'USD' }; - const bids = spec.interpretResponse({body: bidResponse}, request); + const bids = spec.interpretResponse({ body: bidResponse }, request); expect(bids.length).to.equal(1); const bid = bids[0]; it('should return the proper mediaType', function () { @@ -537,7 +537,7 @@ describe('viantOrtbBidAdapter', function () { ], 'cur': 'USD' }; - const bids = spec.interpretResponse({body: VIDEO_BID_RESPONSE}, request); + const bids = spec.interpretResponse({ body: VIDEO_BID_RESPONSE }, request); expect(bids.length).to.equal(1); const bid = bids[0]; it('should return the proper mediaType', function () { diff --git a/test/spec/modules/vibrantmediaBidAdapter_spec.js b/test/spec/modules/vibrantmediaBidAdapter_spec.js index 6aaa84a00c5..4522f383dfe 100644 --- a/test/spec/modules/vibrantmediaBidAdapter_spec.js +++ b/test/spec/modules/vibrantmediaBidAdapter_spec.js @@ -1,8 +1,8 @@ -import {expect} from 'chai'; -import {spec} from 'modules/vibrantmediaBidAdapter.js'; -import {newBidder} from 'src/adapters/bidderFactory.js'; -import {BANNER, NATIVE, VIDEO} from 'src/mediaTypes.js'; -import {INSTREAM, OUTSTREAM} from 'src/video.js'; +import { expect } from 'chai'; +import { spec } from 'modules/vibrantmediaBidAdapter.js'; +import { newBidder } from 'src/adapters/bidderFactory.js'; +import { BANNER, NATIVE, VIDEO } from 'src/mediaTypes.js'; +import { INSTREAM, OUTSTREAM } from 'src/video.js'; import { getWinDimensions } from '../../../src/utils.js'; const EXPECTED_PREBID_SERVER_URL = 'https://prebid.intellitxt.com/prebid'; diff --git a/test/spec/modules/vidazooBidAdapter_spec.js b/test/spec/modules/vidazooBidAdapter_spec.js index ab0820ef32e..54d24f2f540 100644 --- a/test/spec/modules/vidazooBidAdapter_spec.js +++ b/test/spec/modules/vidazooBidAdapter_spec.js @@ -1,4 +1,4 @@ -import {expect} from 'chai'; +import { expect } from 'chai'; import { spec as adapter, storage, @@ -19,12 +19,12 @@ import { getVidazooSessionId } from 'libraries/vidazooUtils/bidderUtils.js' import * as utils from 'src/utils.js'; -import {version} from 'package.json'; -import {useFakeTimers} from 'sinon'; -import {BANNER, VIDEO} from '../../../src/mediaTypes.js'; -import {config} from '../../../src/config.js'; -import {deepSetValue} from 'src/utils.js'; -import {getGlobal} from '../../../src/prebidGlobal.js'; +import { version } from 'package.json'; +import { useFakeTimers } from 'sinon'; +import { BANNER, VIDEO } from '../../../src/mediaTypes.js'; +import { config } from '../../../src/config.js'; +import { deepSetValue } from 'src/utils.js'; +import { getGlobal } from '../../../src/prebidGlobal.js'; export const TEST_ID_SYSTEMS = ['criteoId', 'id5id', 'idl_env', 'lipb', 'netId', 'pubcid', 'tdid', 'pubProvidedId']; @@ -107,9 +107,9 @@ const ORTB2_DEVICE = { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -126,7 +126,7 @@ const ORTB2_DEVICE = { model: 'iPhone 12 Pro Max', os: 'iOS', osv: '17.4', - ext: {fiftyonedegrees_deviceId: '17595-133085-133468-18092'}, + ext: { fiftyonedegrees_deviceId: '17595-133085-133468-18092' }, }; const BIDDER_REQUEST = { @@ -153,8 +153,8 @@ const BIDDER_REQUEST = { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }] } @@ -168,9 +168,9 @@ const BIDDER_REQUEST = { user: { data: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], }, @@ -225,22 +225,22 @@ const VIDEO_SERVER_RESPONSE = { const ORTB2_OBJ = { "device": ORTB2_DEVICE, - "regs": {"coppa": 0, "gpp": "gpp_string", "gpp_sid": [7]}, + "regs": { "coppa": 0, "gpp": "gpp_string", "gpp_sid": [7] }, "site": { "cat": ["IAB2"], "content": { "data": [{ - "ext": {"segtax": 7}, + "ext": { "segtax": 7 }, "name": "example.com", - "segments": [{"id": "segId1"}, {"id": "segId2"}] + "segments": [{ "id": "segId1" }, { "id": "segId2" }] }], "language": "en" }, "pagecat": ["IAB2-2"] }, - "source": {"ext": {"omidpn": "MyIntegrationPartner", "omidpv": "7.1"}}, + "source": { "ext": { "omidpn": "MyIntegrationPartner", "omidpv": "7.1" } }, "user": { - "data": [{"ext": {"segclass": "1", "segtax": 600}, "name": "example.com", "segment": [{"id": "243"}]}] + "data": [{ "ext": { "segclass": "1", "segtax": 600 }, "name": "example.com", "segment": [{ "id": "243" }] }] } }; @@ -375,9 +375,9 @@ describe('VidazooBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -393,15 +393,15 @@ describe('VidazooBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], uniqueDealId: `${hashUrl}_${Date.now().toString()}`, @@ -462,9 +462,9 @@ describe('VidazooBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -506,15 +506,15 @@ describe('VidazooBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], webSessionId: webSessionId @@ -558,9 +558,9 @@ describe('VidazooBidAdapter', function () { 'version': ['8', '0', '0'] }, 'browsers': [ - {'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0']}, - {'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119']}, - {'brand': 'Chromium', 'version': ['109', '0', '5414', '119']} + { 'brand': 'Not_A Brand', 'version': ['99', '0', '0', '0'] }, + { 'brand': 'Google Chrome', 'version': ['109', '0', '5414', '119'] }, + { 'brand': 'Chromium', 'version': ['109', '0', '5414', '119'] } ], 'mobile': 1, 'model': 'SM-G955U', @@ -600,15 +600,15 @@ describe('VidazooBidAdapter', function () { 'segtax': 7 }, 'segments': [ - {'id': 'segId1'}, - {'id': 'segId2'} + { 'id': 'segId1' }, + { 'id': 'segId2' } ] }], userData: [ { - ext: {segtax: 600, segclass: '1'}, + ext: { segtax: 600, segclass: '1' }, name: 'example.com', - segment: [{id: '243'}], + segment: [{ id: '243' }], }, ], webSessionId: webSessionId @@ -626,10 +626,12 @@ describe('VidazooBidAdapter', function () { expect(requests[0]).to.deep.equal({ method: 'POST', url: `${createDomain(SUB_DOMAIN)}/prebid/multi/59db6b3b4ffaa70004f45cdc`, - data: {bids: [ - {...REQUEST_DATA, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp}, - {...REQUEST_DATA2, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp} - ]} + data: { + bids: [ + { ...REQUEST_DATA, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp }, + { ...REQUEST_DATA2, ortb2: ORTB2_OBJ, ortb2Imp: BID.ortb2Imp } + ] + } }); }); @@ -662,7 +664,7 @@ describe('VidazooBidAdapter', function () { it('should set fledge correctly if enabled', function () { config.resetConfig(); const bidderRequest = utils.deepClone(BIDDER_REQUEST); - bidderRequest.paapi = {enabled: true}; + bidderRequest.paapi = { enabled: true }; deepSetValue(bidderRequest, 'ortb2Imp.ext.ae', 1); const requests = adapter.buildRequests([BID], bidderRequest); expect(requests[0].data.fledge).to.equal(1); @@ -677,7 +679,7 @@ describe('VidazooBidAdapter', function () { describe('getUserSyncs', function () { it('should have valid user sync with iframeEnabled', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', @@ -686,7 +688,7 @@ describe('VidazooBidAdapter', function () { }); it('should have valid user sync with cid on response', function () { - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.cootlogix.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0' @@ -694,7 +696,7 @@ describe('VidazooBidAdapter', function () { }); it('should have valid user sync with pixelEnabled', function () { - const result = adapter.getUserSyncs({pixelEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ pixelEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ 'url': 'https://sync.cootlogix.com/api/sync/image/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=0', @@ -706,7 +708,7 @@ describe('VidazooBidAdapter', function () { config.setConfig({ coppa: 1 }); - const result = adapter.getUserSyncs({iframeEnabled: true}, [SERVER_RESPONSE]); + const result = adapter.getUserSyncs({ iframeEnabled: true }, [SERVER_RESPONSE]); expect(result).to.deep.equal([{ type: 'iframe', url: 'https://sync.cootlogix.com/api/sync/iframe/?cid=testcid123&gdpr=0&gdpr_consent=&us_privacy=&coppa=1' @@ -721,12 +723,12 @@ describe('VidazooBidAdapter', function () { }); it('should return empty array when there is no ad', function () { - const responses = adapter.interpretResponse({price: 1, ad: ''}); + const responses = adapter.interpretResponse({ price: 1, ad: '' }); expect(responses).to.be.empty; }); it('should return empty array when there is no price', function () { - const responses = adapter.interpretResponse({price: null, ad: 'great ad'}); + const responses = adapter.interpretResponse({ price: null, ad: 'great ad' }); expect(responses).to.be.empty; }); @@ -822,9 +824,9 @@ describe('VidazooBidAdapter', function () { const userId = (function () { switch (idSystemProvider) { case 'lipb': - return {lipbid: id}; + return { lipbid: id }; case 'id5id': - return {uid: id}; + return { uid: id }; default: return id; } @@ -845,7 +847,7 @@ describe('VidazooBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -856,11 +858,11 @@ describe('VidazooBidAdapter', function () { bid.userIdAsEids = [ { "source": "audigent.com", - "uids": [{"id": "fakeidi6j6dlc6e"}] + "uids": [{ "id": "fakeidi6j6dlc6e" }] }, { "source": "rwdcntrl.net", - "uids": [{"id": "fakeid6f35197d5c", "atype": 1}] + "uids": [{ "id": "fakeid6f35197d5c", "atype": 1 }] } ] const requests = adapter.buildRequests([bid], BIDDER_REQUEST); @@ -875,7 +877,7 @@ describe('VidazooBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] } ] } @@ -890,11 +892,11 @@ describe('VidazooBidAdapter', function () { eids: [ { "source": "pubcid.org", - "uids": [{"id": "fakeid8888dlc6e"}] + "uids": [{ "id": "fakeid8888dlc6e" }] }, { "source": "adserver.org", - "uids": [{"id": "fakeid495ff1"}] + "uids": [{ "id": "fakeid495ff1" }] } ] } @@ -907,18 +909,18 @@ describe('VidazooBidAdapter', function () { describe('alternate param names extractors', function () { it('should return undefined when param not supported', function () { - const cid = extractCID({'c_id': '1'}); - const pid = extractPID({'p_id': '1'}); - const subDomain = extractSubDomain({'sub_domain': 'prebid'}); + const cid = extractCID({ 'c_id': '1' }); + const pid = extractPID({ 'p_id': '1' }); + const subDomain = extractSubDomain({ 'sub_domain': 'prebid' }); expect(cid).to.be.undefined; expect(pid).to.be.undefined; expect(subDomain).to.be.undefined; }); it('should return value when param supported', function () { - const cid = extractCID({'cID': '1'}); - const pid = extractPID({'Pid': '2'}); - const subDomain = extractSubDomain({'subDOMAIN': 'prebid'}); + const cid = extractCID({ 'cID': '1' }); + const pid = extractPID({ 'Pid': '2' }); + const subDomain = extractSubDomain({ 'subDOMAIN': 'prebid' }); expect(cid).to.be.equal('1'); expect(pid).to.be.equal('2'); expect(subDomain).to.be.equal('prebid'); @@ -1031,7 +1033,7 @@ describe('VidazooBidAdapter', function () { now }); setStorageItem(storage, 'myKey', 2020); - const {value, created} = getStorageItem(storage, 'myKey'); + const { value, created } = getStorageItem(storage, 'myKey'); expect(created).to.be.equal(now); expect(value).to.be.equal(2020); expect(typeof value).to.be.equal('number'); @@ -1047,8 +1049,8 @@ describe('VidazooBidAdapter', function () { }); it('should parse JSON value', function () { - const data = JSON.stringify({event: 'send'}); - const {event} = tryParseJSON(data); + const data = JSON.stringify({ event: 'send' }); + const { event } = tryParseJSON(data); expect(event).to.be.equal('send'); }); diff --git a/test/spec/modules/videoModule/adQueue_spec.js b/test/spec/modules/videoModule/adQueue_spec.js index 352b2e984a5..d3ab5cfde4c 100644 --- a/test/spec/modules/videoModule/adQueue_spec.js +++ b/test/spec/modules/videoModule/adQueue_spec.js @@ -70,7 +70,7 @@ describe('Ad Queue Coordinator', function () { }; const coordinator = AdQueueCoordinator(mockVideoCore, mockEvents); coordinator.registerProvider(testId); - coordinator.queueAd('testAdTag', testId, {prefetchedVastXml: ''}); + coordinator.queueAd('testAdTag', testId, { prefetchedVastXml: '' }); setupComplete('', { divId: testId }); expect(mockVideoCore.setAdXml.calledOnce).to.be.true; diff --git a/test/spec/modules/videoModule/pbVideo_spec.js b/test/spec/modules/videoModule/pbVideo_spec.js index 5e8aea82d50..18daf1f76d6 100644 --- a/test/spec/modules/videoModule/pbVideo_spec.js +++ b/test/spec/modules/videoModule/pbVideo_spec.js @@ -120,7 +120,7 @@ describe('Prebid Video', function () { pbVideoFactory(videoCore, getConfig); getConfigCallback({ video: { providers } }); const expectedType = 'test_event'; - const expectedPayload = {'test': 'data'}; + const expectedPayload = { 'test': 'data' }; eventHandler(expectedType, expectedPayload); expect(pbEventsMock.emit.calledOnce).to.be.true; expect(pbEventsMock.emit.getCall(0).args[0]).to.be.equal('video' + expectedType.replace(/^./, expectedType[0].toUpperCase())); @@ -252,7 +252,7 @@ describe('Prebid Video', function () { gamSubmoduleMock.getAdTagUrl.resetHistory(); videoCoreMock.setAdTagUrl.resetHistory(); adQueueCoordinatorMock.queueAd.resetHistory(); - auctionResults = { adUnits: [ expectedAdUnit, {} ] }; + auctionResults = { adUnits: [expectedAdUnit, {}] }; }); let beforeBidRequestCallback; @@ -283,7 +283,7 @@ describe('Prebid Video', function () { requestBids, getHighestCpmBids: () => [] }); - auctionResults.adUnits[1].video = {divId: 'other-div'}; + auctionResults.adUnits[1].video = { divId: 'other-div' }; pbVideoFactory(null, getConfig, pbGlobal, requestBids, pbEvents); beforeBidRequestCallback(() => {}, {}); return auctionEndCallback(auctionResults) @@ -327,7 +327,7 @@ describe('Prebid Video', function () { code: expectedAdUnitCode, video: { divId: expectedDivId } }; - const auctionResults = { adUnits: [ expectedAdUnit, {} ] }; + const auctionResults = { adUnits: [expectedAdUnit, {}] }; pbVideoFactory(null, () => ({ providers: [] }), pbGlobal, requestBids, pbEvents); beforeBidRequestCallback(() => {}, {}); diff --git a/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js b/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js index edf268a829f..1eb48ab897d 100644 --- a/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js +++ b/test/spec/modules/videoModule/shared/vastXmlBuilder_spec.js @@ -1,7 +1,9 @@ -import { buildVastWrapper, getVastNode, getAdNode, getWrapperNode, getAdSystemNode, - getAdTagUriNode, getErrorNode, getImpressionNode } from 'libraries/video/shared/vastXmlBuilder.js'; +import { + buildVastWrapper, getVastNode, getAdNode, getWrapperNode, getAdSystemNode, + getAdTagUriNode, getErrorNode, getImpressionNode +} from 'libraries/video/shared/vastXmlBuilder.js'; import { expect } from 'chai'; -import {getGlobal} from '../../../../../src/prebidGlobal.js'; +import { getGlobal } from '../../../../../src/prebidGlobal.js'; describe('buildVastWrapper', function () { it('should include impression and error nodes when requested', function () { diff --git a/test/spec/modules/videoModule/submodules/adplayerproVideoProvider_spec.js b/test/spec/modules/videoModule/submodules/adplayerproVideoProvider_spec.js index b1d4faabef7..81b5a289849 100644 --- a/test/spec/modules/videoModule/submodules/adplayerproVideoProvider_spec.js +++ b/test/spec/modules/videoModule/submodules/adplayerproVideoProvider_spec.js @@ -16,11 +16,11 @@ import { SETUP_FAILED, VOLUME } from 'libraries/video/constants/events.js'; -import adPlayerProSubmoduleFactory, {callbackStorageFactory} from '../../../../../modules/adplayerproVideoProvider.js'; -import {PLACEMENT} from '../../../../../libraries/video/constants/ortb.js'; +import adPlayerProSubmoduleFactory, { callbackStorageFactory } from '../../../../../modules/adplayerproVideoProvider.js'; +import { PLACEMENT } from '../../../../../libraries/video/constants/ortb.js'; import sinon from 'sinon'; -const {AdPlayerProProvider, utils} = require('modules/adplayerproVideoProvider.js'); +const { AdPlayerProProvider, utils } = require('modules/adplayerproVideoProvider.js'); const { PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, VPAID_MIME_TYPE, PLCMT @@ -93,7 +93,7 @@ describe('AdPlayerProProvider', function () { beforeEach(() => { addDiv(); - config = {divId: 'test', playerConfig: {placementId: 'testId'}}; + config = { divId: 'test', playerConfig: { placementId: 'testId' } }; callbackStorage = callbackStorageFactory(); utilsMock = getUtilsMock(); player = getPlayerMock(); @@ -264,7 +264,7 @@ describe('AdPlayerProProvider', function () { const setupSpy = player.setup = sinon.spy(player.setup); const provider = AdPlayerProProvider(config, makePlayerFactoryMock(player), callbackStorage, utils); provider.init(); - provider.setAdTagUrl('', {adXml: 'https://test.com'}); + provider.setAdTagUrl('', { adXml: 'https://test.com' }); expect(setupSpy.calledOnce).to.be.true; }); @@ -398,15 +398,15 @@ describe('AdPlayerProProvider utils', function () { test(false, PLACEMENT.BANNER); test({}, PLACEMENT.BANNER); - test({type: 'test'}, PLACEMENT.BANNER); - test({type: 'inPage'}, PLACEMENT.ARTICLE); - test({type: 'rewarded'}, PLACEMENT.INTERSTITIAL_SLIDER_FLOATING); - test({type: 'inView'}, PLACEMENT.INTERSTITIAL_SLIDER_FLOATING); + test({ type: 'test' }, PLACEMENT.BANNER); + test({ type: 'inPage' }, PLACEMENT.ARTICLE); + test({ type: 'rewarded' }, PLACEMENT.INTERSTITIAL_SLIDER_FLOATING); + test({ type: 'inView' }, PLACEMENT.INTERSTITIAL_SLIDER_FLOATING); }); it('getPlaybackMethod', function () { function test(autoplay, mute, expected) { - expect(utils.getPlaybackMethod({autoplay, mute})).to.be.equal(expected); + expect(utils.getPlaybackMethod({ autoplay, mute })).to.be.equal(expected); } test(false, false, PLAYBACK_METHODS.CLICK_TO_PLAY); @@ -417,7 +417,7 @@ describe('AdPlayerProProvider utils', function () { it('getPlcmt', function () { function test(type, autoplay, muted, file, expected) { - expect(utils.getPlcmt({type, autoplay, muted, file})).to.be.equal(expected); + expect(utils.getPlcmt({ type, autoplay, muted, file })).to.be.equal(expected); } test('inStream', false, false, 'f', PLCMT.INSTREAM); diff --git a/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js b/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js index c414265129d..284e8a358f0 100644 --- a/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +++ b/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js @@ -348,7 +348,7 @@ describe('JWPlayerProvider', function () { const provider = JWPlayerProvider({ divId: 'test' }, makePlayerFactoryMock(player), {}, {}, {}, {}, sharedUtils); provider.init(); const xml = ''; - const options = {foo: 'bar'}; + const options = { foo: 'bar' }; provider.setAdXml(xml, options); expect(loadSpy.calledOnceWith(xml, options)).to.be.true; }); @@ -2345,44 +2345,44 @@ describe('utils', function () { it('should return an empty object when width and aspectratio are not strings', function () { expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {width: 100})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '1:2', width: 100})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { width: 100 })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '1:2', width: 100 })).to.deep.equal({}); }); it('should return an empty object when aspectratio is malformed', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '0.5', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '1-2', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '1:', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: ':2', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: ':', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '1:2:3', width: '100%'})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '0.5', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '1-2', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '1:', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: ':2', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: ':', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '1:2:3', width: '100%' })).to.deep.equal({}); }); it('should return an empty object when player container cannot be obtained', function () { - expect(getPlayerSizeFromAspectRatio({}, {aspectratio: '1:2', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => undefined }, {aspectratio: '1:2', width: '100%'})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({}, { aspectratio: '1:2', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => undefined }, { aspectratio: '1:2', width: '100%' })).to.deep.equal({}); }); it('should calculate the size given the width percentage and aspect ratio', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '2:1', width: '100%'})).to.deep.equal({ height: 320, width: 640 }); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '4:1', width: '70%'})).to.deep.equal({ height: 112, width: 448 }); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '2:1', width: '100%' })).to.deep.equal({ height: 320, width: 640 }); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '4:1', width: '70%' })).to.deep.equal({ height: 112, width: 448 }); }); it('should return the container height when smaller than the calculated height', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '1:1', width: '100%'})).to.deep.equal({ height: 480, width: 640 }); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '1:1', width: '100%' })).to.deep.equal({ height: 480, width: 640 }); }); it('should handle non-numeric aspect ratio values', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: 'abc:def', width: '100%'})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: 'abc:def', width: '100%' })).to.deep.equal({}); }); it('should handle non-numeric width percentage', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '16:9', width: 'abc%'})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '16:9', width: 'abc%' })).to.deep.equal({}); }); it('should handle zero aspect ratio values', function () { - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '0:9', width: '100%'})).to.deep.equal({}); - expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, {aspectratio: '16:0', width: '100%'})).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '0:9', width: '100%' })).to.deep.equal({}); + expect(getPlayerSizeFromAspectRatio({ getContainer: () => testContainer }, { aspectratio: '16:0', width: '100%' })).to.deep.equal({}); }); }); @@ -2493,7 +2493,7 @@ describe('utils', function () { it('should be FLOATING when player is floating', function () { const player = getPlayerMock(); player.getFloating = () => true; - const placement = getPlacement({outstream: true}, player); + const placement = getPlacement({ outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.FLOATING); }); @@ -2501,19 +2501,19 @@ describe('utils', function () { const player = getPlayerMock(); player.getFloating = () => false; - let placement = getPlacement({placement: 'banner', outstream: true}, player); + let placement = getPlacement({ placement: 'banner', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.BANNER); - placement = getPlacement({placement: 'article', outstream: true}, player); + placement = getPlacement({ placement: 'article', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.ARTICLE); - placement = getPlacement({placement: 'feed', outstream: true}, player); + placement = getPlacement({ placement: 'feed', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.FEED); - placement = getPlacement({placement: 'interstitial', outstream: true}, player); + placement = getPlacement({ placement: 'interstitial', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.INTERSTITIAL); - placement = getPlacement({placement: 'slider', outstream: true}, player); + placement = getPlacement({ placement: 'slider', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.SLIDER); }); @@ -2526,10 +2526,10 @@ describe('utils', function () { const player = getPlayerMock(); player.getFloating = () => false; - let placement = getPlacement({placement: 'BANNER', outstream: true}, player); + let placement = getPlacement({ placement: 'BANNER', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.BANNER); - placement = getPlacement({placement: 'Article', outstream: true}, player); + placement = getPlacement({ placement: 'Article', outstream: true }, player); expect(placement).to.be.equal(PLACEMENT.ARTICLE); }); @@ -2537,7 +2537,7 @@ describe('utils', function () { const player = getPlayerMock(); player.getFloating = () => false; - const placement = getPlacement({placement: 'unknown', outstream: true}, player); + const placement = getPlacement({ placement: 'unknown', outstream: true }, player); expect(placement).to.be.undefined; }); }); @@ -2648,7 +2648,7 @@ describe('utils', function () { }); describe('getIsoLanguageCode', function () { - const sampleAudioTracks = [{language: 'ht'}, {language: 'fr'}, {language: 'es'}, {language: 'pt'}]; + const sampleAudioTracks = [{ language: 'ht' }, { language: 'fr' }, { language: 'es' }, { language: 'pt' }]; it('should return undefined when audio tracks are unavailable', function () { const player = getPlayerMock(); @@ -2708,7 +2708,7 @@ describe('utils', function () { it('should handle audio tracks with missing language property', function () { const player = getPlayerMock(); - player.getAudioTracks = () => [{}, {language: 'en'}, {}]; + player.getAudioTracks = () => [{}, { language: 'en' }, {}]; player.getCurrentAudioTrack = () => 0; const languageCode = utils.getIsoLanguageCode(player); expect(languageCode).to.be.undefined; @@ -2716,7 +2716,7 @@ describe('utils', function () { it('should handle audio tracks with null language property', function () { const player = getPlayerMock(); - player.getAudioTracks = () => [{language: null}, {language: 'en'}, {}]; + player.getAudioTracks = () => [{ language: null }, { language: 'en' }, {}]; player.getCurrentAudioTrack = () => 0; const languageCode = utils.getIsoLanguageCode(player); expect(languageCode).to.be.null; @@ -2758,24 +2758,24 @@ describe('utils', function () { it('should convert segments to objects', function () { const segs = ['a', 'b']; expect(getSegments(segs)).to.deep.equal([ - {id: 'a'}, - {id: 'b'} + { id: 'a' }, + { id: 'b' } ]); }); it('should handle single segment', function () { const segs = ['single']; expect(getSegments(segs)).to.deep.equal([ - {id: 'single'} + { id: 'single' } ]); }); it('should handle segments with special characters', function () { const segs = ['segment-1', 'segment_2', 'segment 3']; expect(getSegments(segs)).to.deep.equal([ - {id: 'segment-1'}, - {id: 'segment_2'}, - {id: 'segment 3'} + { id: 'segment-1' }, + { id: 'segment_2' }, + { id: 'segment 3' } ]); }); @@ -2795,7 +2795,7 @@ describe('utils', function () { }); it('should set media id and segments', function () { - const segments = [{id: 'x'}]; + const segments = [{ id: 'x' }]; expect(getContentDatum('id1', segments)).to.deep.equal({ name: 'jwplayer.com', segment: segments, @@ -2813,7 +2813,7 @@ describe('utils', function () { }); it('should set only segments when media id missing', function () { - const segments = [{id: 'y'}]; + const segments = [{ id: 'y' }]; expect(getContentDatum(null, segments)).to.deep.equal({ name: 'jwplayer.com', segment: segments, diff --git a/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js b/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js index 6646cfb611f..d8f3e105885 100644 --- a/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js +++ b/test/spec/modules/videoModule/submodules/videojsVideoProvider_spec.js @@ -4,7 +4,7 @@ import { } from 'libraries/video/constants/events.js'; import { getWinDimensions } from '../../../../../src/utils.js'; -const {VideojsProvider, utils, adStateFactory, timeStateFactory} = require('modules/videojsVideoProvider'); +const { VideojsProvider, utils, adStateFactory, timeStateFactory } = require('modules/videojsVideoProvider'); const { PROTOCOLS, API_FRAMEWORKS, VIDEO_MIME_TYPE, PLAYBACK_METHODS, PLCMT, VPAID_MIME_TYPE, AD_POSITION @@ -42,7 +42,7 @@ describe('videojsProvider', function () { }); it('should trigger failure when videojs version is under min supported version', function () { - const provider = VideojsProvider(config, {...videojs, VERSION: '0.0.0'}, adState, timeState, callbackStorage, utils); + const provider = VideojsProvider(config, { ...videojs, VERSION: '0.0.0' }, adState, timeState, callbackStorage, utils); const setupFailed = sinon.spy(); provider.onEvent(SETUP_FAILED, setupFailed, {}); provider.init(); @@ -63,7 +63,7 @@ describe('videojsProvider', function () { }); it('should instantiate the player when uninstantied', function () { - config.playerConfig = {testAttr: true}; + config.playerConfig = { testAttr: true }; config.divId = 'test-div' const div = document.createElement('div'); div.setAttribute('id', 'test-div'); @@ -116,7 +116,7 @@ describe('videojsProvider', function () { describe('getOrtbParams', function () { beforeEach(() => { - config = {divId: 'test'}; + config = { divId: 'test' }; // initialize videojs element document.body.innerHTML = `